From 575eaf312d466c5eecc311a42a70fd9fac15cba3 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 13 Jan 2020 09:27:43 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13269 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk | 11 - os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c | 286 --- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h | 29 - .../ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c | 173 -- .../ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h | 71 - os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c | 234 -- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h | 25 - os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c | 477 ---- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h | 26 - .../ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c | 297 --- .../ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h | 61 - os/hal/ports/SAMA/LLD/DMAv1/driver.mk | 2 - os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c | 303 --- os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.h | 311 --- os/hal/ports/SAMA/LLD/I2Cv1/driver.mk | 21 - os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c | 963 --------- os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.h | 277 --- os/hal/ports/SAMA/LLD/MACv1/driver.mk | 9 - os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c | 852 -------- os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.h | 329 --- os/hal/ports/SAMA/LLD/PIOv1/driver.mk | 9 - os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c | 387 ---- os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h | 559 ----- os/hal/ports/SAMA/LLD/RNGv1/driver.mk | 9 - os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c | 175 -- os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.h | 113 - os/hal/ports/SAMA/LLD/RTCv1/driver.mk | 9 - os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c | 658 ------ os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.h | 177 -- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.c | 512 ----- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.h | 177 -- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.c | 1255 ----------- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.h | 273 --- .../ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.c | 1917 ----------------- .../ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.h | 384 ---- .../ports/SAMA/LLD/SDMMCv1/ch_sdmmc_macros.h | 38 - os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.c | 377 ---- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.h | 8 - .../ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sama5d2.h | 50 - os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.c | 1197 ---------- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.h | 117 - os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.c | 293 --- os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.h | 295 --- .../ports/SAMA/LLD/SDMMCv1/ch_sdmmc_trace.h | 104 - os/hal/ports/SAMA/LLD/SDMMCv1/driver.mk | 20 - .../ports/SAMA/LLD/SDMMCv1/sama_sdmmc_conf.h | 28 - .../ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.c | 319 --- .../ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.h | 165 -- os/hal/ports/SAMA/LLD/SPIv1/driver.mk | 9 - os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c | 968 --------- os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h | 493 ----- os/hal/ports/SAMA/LLD/USARTv1/driver.mk | 13 - .../ports/SAMA/LLD/USARTv1/hal_serial_lld.c | 1037 --------- .../ports/SAMA/LLD/USARTv1/hal_serial_lld.h | 567 ----- os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c | 1509 ------------- os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.h | 656 ------ os/hal/ports/SAMA/LLD/xWDGv1/driver.mk | 9 - os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c | 165 -- os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.h | 141 -- os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c | 1762 --------------- os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h | 448 ---- os/hal/ports/SAMA/SAMA5D2x/hal_lld.c | 237 -- os/hal/ports/SAMA/SAMA5D2x/hal_lld.h | 545 ----- os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c | 233 -- os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h | 295 --- os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c | 575 ----- os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.h | 357 --- os/hal/ports/SAMA/SAMA5D2x/platform.mk | 47 - os/hal/ports/SAMA/SAMA5D2x/sama_aic.c | 310 --- os/hal/ports/SAMA/SAMA5D2x/sama_aic.h | 114 - os/hal/ports/SAMA/SAMA5D2x/sama_cache.c | 113 - os/hal/ports/SAMA/SAMA5D2x/sama_cache.h | 49 - os/hal/ports/SAMA/SAMA5D2x/sama_classd.c | 526 ----- os/hal/ports/SAMA/SAMA5D2x/sama_classd.h | 301 --- os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.c | 955 -------- os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.h | 280 --- os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c | 241 --- os/hal/ports/SAMA/SAMA5D2x/sama_matrix.h | 341 --- os/hal/ports/SAMA/SAMA5D2x/sama_onewire.c | 548 ----- os/hal/ports/SAMA/SAMA5D2x/sama_onewire.h | 127 -- os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h | 1030 --------- os/hal/ports/SAMA/SAMA5D2x/sama_registry.h | 87 - os/hal/ports/SAMA/SAMA5D2x/sama_rstc.h | 179 -- os/hal/ports/SAMA/SAMA5D2x/sama_secumod.c | 599 ----- os/hal/ports/SAMA/SAMA5D2x/sama_secumod.h | 572 ----- os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.c | 575 ----- os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.h | 364 ---- 87 files changed, 31759 deletions(-) delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/DMAv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c delete mode 100644 os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.h delete mode 100644 os/hal/ports/SAMA/LLD/I2Cv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/MACv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/PIOv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/RNGv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/RTCv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_macros.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sama5d2.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_trace.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_conf.h delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/SPIv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/USARTv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.h delete mode 100644 os/hal/ports/SAMA/LLD/xWDGv1/driver.mk delete mode 100644 os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c delete mode 100644 os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_lld.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_lld.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/platform.mk delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_aic.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_aic.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_cache.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_cache.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_classd.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_classd.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_matrix.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_onewire.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_onewire.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_registry.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_rstc.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_secumod.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_secumod.h delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.c delete mode 100644 os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.h diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk deleted file mode 100644 index 24fcc73b3..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk +++ /dev/null @@ -1,11 +0,0 @@ -PLATFORMSRC +=$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c - - - -PLATFORMINC +=$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1 - - diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c deleted file mode 100644 index a6cb4ee12..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 "hal.h" - -#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) - -#include "sama_crypto_lld.h" - -void sama_aes_lld_write_key(const uint32_t * key, const uint32_t * vectors, - uint32_t len) { - - AES->AES_KEYWR[0] = key[0]; - AES->AES_KEYWR[1] = key[1]; - AES->AES_KEYWR[2] = key[2]; - AES->AES_KEYWR[3] = key[3]; - - if (len >= 24) { - AES->AES_KEYWR[4] = key[4]; - AES->AES_KEYWR[5] = key[5]; - } - - else { - AES->AES_KEYWR[4] = 0; - AES->AES_KEYWR[5] = 0; - AES->AES_KEYWR[6] = 0; - AES->AES_KEYWR[7] = 0; - } - - if (len == 32) { - AES->AES_KEYWR[6] = key[6]; - AES->AES_KEYWR[7] = key[7]; - } - - if (vectors != NULL) { - AES->AES_IVR[0] = vectors[0]; - AES->AES_IVR[1] = vectors[1]; - AES->AES_IVR[2] = vectors[2]; - AES->AES_IVR[3] = vectors[3]; - } - - else { - AES->AES_IVR[0] = 0; - AES->AES_IVR[1] = 0; - AES->AES_IVR[2] = 0; - AES->AES_IVR[3] = 0; - } - -} - -cryerror_t sama_aes_lld_set_key_size(size_t size) { - - uint32_t key_size = AES_MR_KEYSIZE_AES128; - - if (size == 16) - key_size = AES_MR_KEYSIZE_AES128; - else if (size == 24) - key_size = AES_MR_KEYSIZE_AES192; - else if (size == 32) - key_size = AES_MR_KEYSIZE_AES256; - else - return CRY_ERR_INV_KEY_SIZE; - //set key size - AES->AES_MR |= (( AES_MR_KEYSIZE_Msk & (key_size)) | AES_MR_CKEY_PASSWD); - - return CRY_NOERROR; -} - -void sama_aes_lld_set_input(uint32_t* data) { - uint8_t i; - uint8_t size = 4; - - if ((AES->AES_MR & AES_MR_OPMOD_Msk) == AES_MR_OPMOD_CFB) { - if ((AES->AES_MR & AES_MR_CFBS_Msk) == AES_MR_CFBS_SIZE_128BIT) - size = 4; - else if ((AES->AES_MR & AES_MR_CFBS_Msk) == AES_MR_CFBS_SIZE_64BIT) - size = 2; - else - size = 1; - } - - for (i = 0; i < size; i++) { - AES->AES_IDATAR[i] = data[i]; - } - -} - -void sama_aes_lld_get_output(uint32_t* data) { - uint8_t i; - - for (i = 0; i < 4; i++) { - data[i] = (AES->AES_ODATAR[i]); - } -} - -cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp, aesparams *params, - const uint8_t *in, uint8_t *out, size_t indata_len) { - uint32_t i; - cryerror_t ret; - - osalMutexLock(&cryp->mutex); - //AES soft reset - AES->AES_CR = AES_CR_SWRST; - - //AES set op mode - AES->AES_MR |= ((AES_MR_OPMOD_Msk & (params->mode)) | AES_MR_CKEY_PASSWD); - - //AES set key size - ret = sama_aes_lld_set_key_size(cryp->key0_size); - - if (ret == CRY_NOERROR) { - - AES->AES_MR |= (AES_MR_CFBS(cryp->config->cfbs) | AES_MR_CKEY_PASSWD); - - - - sama_aes_lld_write_key(cryp->key0_buffer,( const uint32_t *) params->iv, cryp->key0_size); - - - - if (params->encrypt) - AES->AES_MR |= AES_MR_CIPHER; - else - AES->AES_MR &= ~AES_MR_CIPHER; - - AES->AES_MR |= (((AES_MR_SMOD_Msk & (AES_MR_SMOD_MANUAL_START))) | AES_MR_CKEY_PASSWD); - - //Enable aes interrupt - AES->AES_IER = AES_IER_DATRDY; - - for (i = 0; i < indata_len; i += params->block_size) { - - sama_aes_lld_set_input((uint32_t *) ((in) + i)); - - AES->AES_CR = AES_CR_START; - - while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); - - sama_aes_lld_get_output((uint32_t *) ((out) + i)); - } - - } - - osalMutexUnlock(&cryp->mutex); - - return CRY_NOERROR; - -} - -cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp, aesparams *params, - const uint8_t *in, uint8_t *out, size_t indata_len) { -#if defined(SAMA_DMA_REQUIRED) - cryerror_t ret; - - osalDbgAssert(cryp->thread == NULL, "already waiting"); - osalDbgAssert(!((uint32_t) in & (L1_CACHE_BYTES - 1)), "in address not cache aligned"); - osalDbgAssert(!((uint32_t) out & (L1_CACHE_BYTES - 1)), "out address not cache aligned"); - -#if 0 - osalDbgAssert(!(indata_len & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - /* - * If size is not multiple of cache line, clean cache region is required. - * TODO: remove when size assert works - */ - if (indata_len & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) out, indata_len); - } - - osalMutexLock(&cryp->mutex); - - cacheCleanRegion((uint8_t *) in, indata_len); - - cryp->out = out; - cryp->in = in; - cryp->len = indata_len; - - //set chunk size - cryp->dmachunksize = DMA_CHUNK_SIZE_4; - - if ((cryp->config->cfbs != AES_CFBS_128)) - cryp->dmachunksize = DMA_CHUNK_SIZE_1; - - //set dma width - cryp->dmawith = DMA_DATA_WIDTH_WORD; - - if (cryp->config->cfbs == AES_CFBS_16) - cryp->dmawith = DMA_DATA_WIDTH_HALF_WORD; - if (cryp->config->cfbs == AES_CFBS_8) - cryp->dmawith = DMA_DATA_WIDTH_BYTE; - - cryp->rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_AES_RX); - - cryp->txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_AES_TX); - - dmaChannelSetMode(cryp->dmarx, cryp->rxdmamode); - dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); - - // Writing channel - dmaChannelSetSource(cryp->dmatx, in); - dmaChannelSetDestination(cryp->dmatx, AES->AES_IDATAR); - dmaChannelSetTransactionSize(cryp->dmatx, ( indata_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - - // Reading channel - dmaChannelSetSource(cryp->dmarx, AES->AES_ODATAR); - dmaChannelSetDestination(cryp->dmarx, out); - dmaChannelSetTransactionSize(cryp->dmarx, ( indata_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - //AES soft reset - AES->AES_CR = AES_CR_SWRST; - - //AES set op mode - AES->AES_MR |= ((AES_MR_OPMOD_Msk & (params->mode)) | AES_MR_CKEY_PASSWD); - - //AES set key size - ret = sama_aes_lld_set_key_size(cryp->key0_size); - - if (ret == CRY_NOERROR) { - - AES->AES_MR |= (AES_MR_CFBS(cryp->config->cfbs) | AES_MR_CKEY_PASSWD); - - sama_aes_lld_write_key(cryp->key0_buffer,( const uint32_t *) params->iv, cryp->key0_size); - - if (params->encrypt) - AES->AES_MR |= AES_MR_CIPHER; - else - AES->AES_MR &= ~AES_MR_CIPHER; - - AES->AES_MR |= (((AES_MR_SMOD_Msk & (AES_MR_SMOD_IDATAR0_START))) - | AES_MR_CKEY_PASSWD); - - //Enable aes interrupt - AES->AES_IER = AES_IER_DATRDY; - - } - - osalSysLock(); - - dmaChannelEnable(cryp->dmarx); - dmaChannelEnable(cryp->dmatx); - - osalThreadSuspendS(&cryp->thread); - - osalSysUnlock(); - - osalMutexUnlock(&cryp->mutex); -#endif //#if defined(SAMA_DMA_REQUIRED) - return CRY_NOERROR; - -} - -#endif /* HAL_USE_CRY */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h deleted file mode 100644 index 3875287e6..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 CRYPTOLIB_LLD_SAMA_AES_H_ -#define CRYPTOLIB_LLD_SAMA_AES_H_ - -extern void sama_aes_lld_write_key(const uint32_t * key, const uint32_t * vectors,uint32_t len); -extern cryerror_t sama_aes_lld_set_key_size(size_t size); -extern cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp,aesparams *params,const uint8_t *in,uint8_t *out,size_t indata_len); -extern cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp,aesparams *params,const uint8_t *in,uint8_t *out,size_t indata_len); - -extern void sama_aes_lld_set_input(uint32_t* data); -extern void sama_aes_lld_get_output(uint32_t* data); - - - -#endif /* CRYPTOLIB_LLD_SAMA_AES_H_ */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c deleted file mode 100644 index 764b1b915..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 "hal.h" - -#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) - -#include "sama_crypto_lld.h" - -#if defined(SAMA_DMA_REQUIRED) -static void crypto_lld_serve_read_interrupt(CRYDriver *cryp, uint32_t flags); -static void crypto_lld_serve_write_interrupt(CRYDriver *cryp, uint32_t flags); -#endif - -/** - * @brief Wakes up the waiting thread. - * - * @param[in] cryp pointer to the @p CRYDRiver object - * - * @notapi - */ -#define _cry_wakeup_isr(cryp) { \ - osalSysLockFromISR(); \ - osalThreadResumeI(&cryp->thread, MSG_OK); \ - osalSysUnlockFromISR(); \ -} - - -/** - * @brief Common ISR code. - * @details This code handles the portable part of the ISR code: - * - Callback invocation. - * - Waiting thread wakeup, if any. - * - Driver state transitions. - * . - * @note This macro is meant to be used in the low level drivers - * implementation only. - * - * @param[in] cryp pointer to the @p CRYDriver object - * - * @notapi - */ -#define _cry_isr_code(cryp) { \ - _cry_wakeup_isr(cryp); \ -} - -void samaCryptoDriverInit(CRYDriver *cryp) { - cryp->enabledPer = 0; - cryp->thread = NULL; - osalMutexObjectInit(&cryp->mutex); -} - -void samaCryptoDriverStart(CRYDriver *cryp) { - - - if (cryp->config->transfer_mode == TRANSFER_DMA) - { -#if defined(SAMA_DMA_REQUIRED) - cryp->dmarx = dmaChannelAllocate(SAMA_CRY_CRYD1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t) crypto_lld_serve_read_interrupt, (void *) cryp); - osalDbgAssert(cryp->dmarx != NULL, "no channel allocated"); - - cryp->dmatx = dmaChannelAllocate(SAMA_CRY_CRYD1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t) crypto_lld_serve_write_interrupt, (void *) cryp); - osalDbgAssert(cryp->dmatx != NULL, "no channel allocated"); -#endif - } - -} - -void samaCryptoDriverStop(CRYDriver *cryp) { -#if defined(SAMA_DMA_REQUIRED) - if (cryp->config->transfer_mode == TRANSFER_DMA) - { - dmaChannelRelease(cryp->dmarx); - dmaChannelRelease(cryp->dmatx); - } -#endif - samaCryptoDriverDisable(cryp); -} - -void samaCryptoDriverDisable(CRYDriver *cryp) -{ - if ((cryp->enabledPer & AES_PER)) { - cryp->enabledPer &= ~AES_PER; - pmcDisableAES(); - } - if ((cryp->enabledPer & TDES_PER)) { - cryp->enabledPer &= ~TDES_PER; - pmcDisableDES(); - } - if ((cryp->enabledPer & SHA_PER)) { - cryp->enabledPer &= ~SHA_PER; - pmcDisableSHA(); - } - if ((cryp->enabledPer & TRNG_PER)) { - cryp->enabledPer &= ~TRNG_PER; - TRNG->TRNG_CR = TRNG_CR_KEY_PASSWD; - pmcDisableTRNG(); - } -} - -#if defined(SAMA_DMA_REQUIRED) -/** - * @brief Shared end-of-rx service routine. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void crypto_lld_serve_read_interrupt(CRYDriver *cryp, uint32_t flags) { - - /* DMA errors handling.*/ - #if defined(SAMA_CRY_DMA_ERROR_HOOK) - if ((flags & (XDMAC_CIS_RBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_CRY_DMA_ERROR_HOOK(cryp); - } -#else - (void)flags; -#endif - - /* D-Cache L1 is enabled */ - cacheInvalidateRegion(cryp->out, cryp->len); - - /* Stop everything.*/ - dmaChannelDisable(cryp->dmarx); - /* Portable CRY ISR code defined in the high level driver, note, it is - a macro.*/ - _cry_isr_code(cryp); -} - -/** - * @brief Shared end-of-tx service routine. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void crypto_lld_serve_write_interrupt(CRYDriver *cryp, uint32_t flags) { - - /* DMA errors handling.*/ - -#if defined(SAMA_CRY_DMA_ERROR_HOOK) - (void)cryp; - if ((flags & (XDMAC_CIS_WBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_CRY_DMA_ERROR_HOOK(cryp); - } -#else - (void)cryp; - (void)flags; -#endif - - dmaChannelDisable(cryp->dmatx); - - if (cryp->rxdmamode == 0xFFFFFFFF) - _cry_isr_code(cryp); -} - -#endif - -#endif /* HAL_USE_CRY */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h deleted file mode 100644 index b90535392..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA_CRYPTO_LLD_H_ -#define SAMA_CRYPTO_LLD_H_ - -#if HAL_USE_CRY || defined(__DOXYGEN__) - -extern void samaCryptoDriverInit(CRYDriver *cryp); -extern void samaCryptoDriverStart(CRYDriver *cryp); -extern void samaCryptoDriverStop(CRYDriver *cryp); -extern void samaCryptoDriverDisable(CRYDriver *cryp); - - -#define AES_PER 0x01 -#define TRNG_PER 0x02 -#define SHA_PER 0x04 -#define TDES_PER 0x08 - -#define DMA_DATA_WIDTH_BYTE 0 -#define DMA_DATA_WIDTH_HALF_WORD 1 -#define DMA_DATA_WIDTH_WORD 2 -#define DMA_DATA_WIDTH_DWORD 3 - -#define DMA_CHUNK_SIZE_1 0 -#define DMA_CHUNK_SIZE_2 1 -#define DMA_CHUNK_SIZE_4 2 -#define DMA_CHUNK_SIZE_8 3 -#define DMA_CHUNK_SIZE_16 4 - -#define DMA_DATA_WIDTH_TO_BYTE(w) (1 << w) - -#ifndef SAMA_CRY_CRYD1_DMA_IRQ_PRIORITY -#define SAMA_CRY_CRYD1_DMA_IRQ_PRIORITY 4 -#endif - -#ifndef SAMA_CRY_CRYD1_IRQ_PRIORITY -#define SAMA_CRY_CRYD1_IRQ_PRIORITY 4 -#endif - -#ifndef SAMA_CRY_DMA_ERROR_HOOK -#define SAMA_CRY_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure") -#endif - -#ifndef SAMA_CRY_SHA_UPDATE_LEN_MAX -#define SAMA_CRY_SHA_UPDATE_LEN_MAX 128*1024 -#endif - - -#include "sama_aes_lld.h" -#include "sama_tdes_lld.h" -#include "sama_sha_lld.h" -#include "sama_gcm_lld.h" - -#endif /* HAL_USE_CRY */ - -#endif //SAMA_CRYPTO_LLD_H_ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c deleted file mode 100644 index 3e9471a2a..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 "hal.h" -#include -#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) - -#include "sama_crypto_lld.h" - -static void incr32(uint8_t* j0) -{ - - uint32_t counter = j0[15] | j0[14] << 0x8 | j0[13] << 0x10 | j0[12] << 0x18; - - counter++; - - j0[12] = (counter>>24) & 0xFF; - j0[13] = (counter>>16) & 0xFF; - j0[14] = (counter>>8) & 0xFF; - j0[15] = counter & 0xFF; -} - -static cryerror_t sama_gcm_lld_process_dma(CRYDriver *cryp,cgmcontext * cxt) -{ -#if defined(SAMA_DMA_REQUIRED) - - osalDbgAssert(!((uint32_t) cxt->in & (L1_CACHE_BYTES - 1)), "in address not cache aligned"); - osalDbgAssert(!((uint32_t) cxt->out & (L1_CACHE_BYTES - 1)), "out address not cache aligned"); - osalDbgAssert(cryp->thread == NULL, "already waiting"); - -#if 0 - osalDbgAssert(!(cxt->c_size & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - cacheCleanRegion((uint8_t *) cxt->in, cxt->c_size); - - /* - * If size is not multiple of cache line, clean cache region is required. - * TODO: remove when size assert works - */ - if (cxt->c_size & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) cxt->out, cxt->c_size); - } - - cryp->out = cxt->out; - cryp->in = cxt->in; - cryp->len = cxt->c_size; - - //set chunk size - cryp->dmachunksize = DMA_CHUNK_SIZE_4; - - if ((cryp->config->cfbs != AES_CFBS_128)) - cryp->dmachunksize = DMA_CHUNK_SIZE_1; - - //set dma width - cryp->dmawith = DMA_DATA_WIDTH_WORD; - - if (cryp->config->cfbs == AES_CFBS_16) - cryp->dmawith = DMA_DATA_WIDTH_HALF_WORD; - if (cryp->config->cfbs == AES_CFBS_8) - cryp->dmawith = DMA_DATA_WIDTH_BYTE; - - cryp->rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_AES_RX); - - cryp->txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_AES_TX); - - dmaChannelSetMode(cryp->dmarx, cryp->rxdmamode); - dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); - - // Writing channel - dmaChannelSetSource(cryp->dmatx, cxt->in); - dmaChannelSetDestination(cryp->dmatx, AES->AES_IDATAR); - dmaChannelSetTransactionSize(cryp->dmatx, ( cxt->c_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - - // Reading channel - dmaChannelSetSource(cryp->dmarx, AES->AES_ODATAR); - dmaChannelSetDestination(cryp->dmarx, cxt->out); - dmaChannelSetTransactionSize(cryp->dmarx, ( cxt->c_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - AES->AES_MR |= (((AES_MR_SMOD_Msk & (AES_MR_SMOD_IDATAR0_START))) - | AES_MR_CKEY_PASSWD); - - //Enable aes interrupt - AES->AES_IER = AES_IER_DATRDY; - - osalSysLock(); - - dmaChannelEnable(cryp->dmarx); - dmaChannelEnable(cryp->dmatx); - - osalThreadSuspendS(&cryp->thread); - - osalSysUnlock(); - - -#endif //#if defined(SAMA_DMA_REQUIRED) - return CRY_NOERROR; - -} - -cryerror_t sama_gcm_lld_process(CRYDriver *cryp,cgmcontext * cxt) -{ - cryerror_t ret; - uint32_t *ref32; - uint8_t i; - uint8_t J0[16] = { 0x00 }; - - - osalMutexLock(&cryp->mutex); - - - //AES soft reset - AES->AES_CR = AES_CR_SWRST; - - //AES set op mode - AES->AES_MR =((AES_MR_OPMOD_Msk & (AES_MR_OPMOD_GCM)) | AES_MR_GTAGEN | AES_MR_CKEY_PASSWD); - - - //AES set key size - ret = sama_aes_lld_set_key_size(cryp->key0_size); - - - if (ret == CRY_NOERROR) { - - AES->AES_MR |= ( ((AES_MR_SMOD_Msk & (AES_MR_SMOD_MANUAL_START))) | AES_MR_CKEY_PASSWD); - - sama_aes_lld_write_key(cryp->key0_buffer,NULL, cryp->key0_size); - - AES->AES_CR = AES_CR_START; - - while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); - - //J0 - - memcpy(J0, cxt->params.iv, 16); // copy the IV to the first 12 bytes of J0 - - incr32(J0); - - // Write incr32(J0) into IV. - - ref32 = (uint32_t*)J0; - AES->AES_IVR[0] = ref32[0]; - AES->AES_IVR[1] = ref32[1]; - AES->AES_IVR[2] = ref32[2]; - AES->AES_IVR[3] = ref32[3]; - - - AES->AES_AADLENR = cxt->aadsize; - AES->AES_CLENR = cxt->c_size; - - if (cxt->params.encrypt) - AES->AES_MR |= AES_MR_CIPHER; - else - AES->AES_MR &= ~AES_MR_CIPHER; - - AES->AES_MR |= AES_MR_GTAGEN| AES_MR_CKEY_PASSWD; - - - for (i = 0; i < cxt->aadsize; i += cxt->params.block_size) { - - sama_aes_lld_set_input((uint32_t *) ((cxt->aad) + i)); - - AES->AES_CR = AES_CR_START; - - while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); - - } - - if (cryp->config->transfer_mode == TRANSFER_POLLING) { - for (i = 0; i < cxt->c_size; i += cxt->params.block_size) { - - sama_aes_lld_set_input((uint32_t *) ((cxt->in) + i)); - - AES->AES_CR = AES_CR_START; - - while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); - - sama_aes_lld_get_output((uint32_t *) ((cxt->out) + i)); - } - } - else - { - sama_gcm_lld_process_dma(cryp,cxt); - } - - while ((AES->AES_ISR & AES_ISR_TAGRDY) != AES_ISR_TAGRDY); - - ref32 = (uint32_t*)cxt->authtag; - - for (i = 0; i < 4; i++) { - ref32[i] =AES->AES_TAGR[i]; - } - - - } - osalMutexUnlock(&cryp->mutex); - - return ret; - -} - - -#endif diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h deleted file mode 100644 index 1ce7c3c19..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 CRYPTOLIB_LLD_SAMA_GCM_H_ -#define CRYPTOLIB_LLD_SAMA_GCM_H_ - - - -cryerror_t sama_gcm_lld_process(CRYDriver *cryp,cgmcontext * cxt); - - - -#endif /* CRYPTOLIB_LLD_SAMA_GCM_H_ */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c deleted file mode 100644 index cf38e75d0..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 "hal.h" -#include -#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) - -#include "sama_crypto_lld.h" - - -static inline uint32_t min_u32(uint32_t a, uint32_t b) -{ - return a < b ? a : b; -} - - - -static uint32_t shaOutputSize(shadalgo_t algo); -static uint32_t shadPaddedMessSize(uint8_t mode, uint32_t len); -uint8_t shaBlockSize(shadalgo_t algo); -static void loadData(const uint8_t* data, int len); -static void readData(const uint8_t* data, int len); -static uint32_t processBlockPolling(const uint8_t *data,uint32_t len, uint32_t block_size); -static uint32_t processBlockDMA(CRYDriver *cryp,const uint8_t *data, uint32_t len, uint32_t block_size); -static void update(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size); - -static uint32_t fillPadding(struct sha_data *shadata, uint32_t len, uint8_t* buffer,size_t buffer_size); - - - -uint8_t shaDigestSize(shadalgo_t algo); - -uint8_t shaDigestSize(shadalgo_t algo) -{ - switch(algo) - { - case CRY_SHA_1: - return 20; - break; - case CRY_SHA_224: - return 28; - break; - case CRY_SHA_256: - return 32; - break; - case CRY_SHA_384: - return 48; - break; - case CRY_SHA_512: - return 64; - break; - default: - return 0; - } -} - - - - -static cryerror_t sha_finish(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* buffer,uint32_t buffer_size) -{ - - uint32_t padding_len=0; - - - if (buffer_size < shadata->output_size) - return CRY_ERR_INV_ALGO; - - //pad data for the end of the buffer - padding_len = fillPadding(shadata,shadata->processed + shadata->remaining,&shadata->sha_buffer[shadata->remaining],shadata->sha_buffer_size - shadata->remaining); - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - processBlockPolling(shadata->sha_buffer,shadata->remaining + padding_len, shadata->block_size); - else - processBlockDMA(cryp,shadata->sha_buffer,shadata->remaining + padding_len, shadata->block_size); - - readData(buffer, buffer_size); - return CRY_NOERROR; - -} - -cryerror_t sama_sha_lld_update(CRYDriver *cryp, struct sha_data *sha) -{ - uint32_t buf_in_size; - uint8_t* p; - osalMutexLock(&cryp->mutex); - - p = (uint8_t*)sha->in; - - while (sha->indata_len) { - buf_in_size = min_u32(sha->indata_len, SAMA_CRY_SHA_UPDATE_LEN_MAX); - - //First block - if (!sha->processed) { - SHA->SHA_CR = SHA_CR_FIRST; - } - - update(cryp, sha, p, buf_in_size); - - sha->indata_len -= buf_in_size; - p += buf_in_size; - } - osalMutexUnlock(&cryp->mutex); - - return CRY_NOERROR; -} - -cryerror_t sama_sha_lld_final(CRYDriver *cryp, struct sha_data *sha) -{ - cryerror_t err = CRY_NOERROR; - osalMutexLock(&cryp->mutex); - - if (!sha->processed) { - SHA->SHA_CR = SHA_CR_FIRST; - } - - err = sha_finish(cryp, sha, sha->out, sha->output_size); - - osalMutexUnlock(&cryp->mutex); - - return err; -} - - - -cryerror_t sama_sha_lld_init(CRYDriver *cryp, struct sha_data *sha) -{ - uint32_t algoregval; - cryerror_t cryerr = CRY_NOERROR; - - if (!(cryp->enabledPer & SHA_PER)) { - cryp->enabledPer |= SHA_PER; - pmcEnableSHA(); - } - - osalMutexLock(&cryp->mutex); - - - sha->processed = 0; - sha->remaining = 0; - sha->output_size = shaOutputSize(sha->algo); - sha->block_size = shaBlockSize(sha->algo); - - - if (sha->output_size == 0) { - osalMutexUnlock(&cryp->mutex); - return CRY_ERR_INV_ALGO; - } - - switch (sha->algo) { - case CRY_SHA_1: - algoregval = SHA_MR_ALGO_SHA1; - break; - case CRY_SHA_224: - algoregval = SHA_MR_ALGO_SHA224; - break; - case CRY_SHA_256: - algoregval = SHA_MR_ALGO_SHA256; - break; -#ifdef SHA_MR_ALGO_SHA384 - case CRY_SHA_384: - algoregval = SHA_MR_ALGO_SHA384; - break; -#endif -#ifdef SHA_MR_ALGO_SHA512 - case CRY_SHA_512: - algoregval = SHA_MR_ALGO_SHA512; - break; -#endif - case CRY_HMACSHA_1: - algoregval = SHA_MR_ALGO_HMAC_SHA1; - break; - case CRY_HMACSHA_224: - algoregval = SHA_MR_ALGO_HMAC_SHA224; - break; - case CRY_HMACSHA_256: - algoregval = SHA_MR_ALGO_HMAC_SHA256; - break; - case CRY_HMACSHA_384: - algoregval = SHA_MR_ALGO_HMAC_SHA384; - break; - case CRY_HMACSHA_512: - algoregval = SHA_MR_ALGO_HMAC_SHA512; - break; - default: - osalMutexUnlock(&cryp->mutex); - return CRY_ERR_INV_ALGO; - } - - - //soft reset - SHA->SHA_CR = SHA_CR_SWRST; - - - if (cryp->config->transfer_mode == TRANSFER_POLLING) { - algoregval |= SHA_MR_SMOD_MANUAL_START; - } else { - algoregval |= SHA_MR_SMOD_IDATAR0_START; - - cryp->dmawith = DMA_DATA_WIDTH_WORD; - cryp->dmachunksize = DMA_CHUNK_SIZE_16; - - cryp->txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_SHA_TX); - - cryp->rxdmamode = 0xFFFFFFFF; - - dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); - } - - //configure - SHA->SHA_MR = algoregval | SHA_MR_PROCDLY_LONGEST; - - //enable interrupt - SHA->SHA_IER = SHA_IER_DATRDY; - - - - osalMutexUnlock(&cryp->mutex); - - return cryerr; -} - - - -static uint32_t shaOutputSize(shadalgo_t algo) -{ - switch (algo) { - case CRY_SHA_1: - case CRY_HMACSHA_1: - return 20; - case CRY_SHA_224: - case CRY_HMACSHA_224: - return 28; - case CRY_SHA_256: - case CRY_HMACSHA_256: - return 32; - case CRY_SHA_384: - case CRY_HMACSHA_384: - return 48; - case CRY_SHA_512: - case CRY_HMACSHA_512: - return 64; - default: - return 0; - } -} - -static uint32_t shadPaddedMessSize(uint8_t mode, uint32_t len) -{ - uint32_t k; - - switch (mode) { - case CRY_SHA_1: - case CRY_SHA_224: - case CRY_SHA_256: - case CRY_HMACSHA_1: - case CRY_HMACSHA_224: - case CRY_HMACSHA_256: - k = (512 + 448 - (((len * 8) % 512) + 1)) % 512; - len += (k - 7) / 8 + 9; - break; - case CRY_SHA_384: - case CRY_SHA_512: - case CRY_HMACSHA_384: - case CRY_HMACSHA_512: - k = (1024 + 896 - (((len * 8) % 1024) + 1)) % 1024; - len += (k - 7) / 8 + 17; - break; - } - return len; -} - -uint8_t shaBlockSize(shadalgo_t algo) -{ - - switch(algo) - { - case CRY_SHA_384: - case CRY_HMACSHA_384: - case CRY_SHA_512: - case CRY_HMACSHA_512: - return 128; - - default: - break; - } - - return 64; -} - - -static void loadData(const uint8_t* data, int len) -{ - int i; - int32_t value; - - for (i = 0; i < (len / 4) && i < 32; i++) { - memcpy(&value, &data[i * 4], 4); - if (i < 16) - SHA->SHA_IDATAR[i] = value; - else - SHA->SHA_IODATAR[i - 16] = value; - } -} - -static void readData(const uint8_t* data, int len) -{ - int i; - int32_t value; - - for (i = 0; i < (len / 4) && i < 16; i++) { - value = SHA->SHA_IODATAR[i]; - memcpy((uint8_t*)&data[i * 4], &value, 4); - } -} - - -static uint32_t processBlockPolling(const uint8_t *data,uint32_t len, uint32_t block_size) -{ - uint32_t processed = 0; - - - while ((len - processed) >= block_size) { - - // load data in the sha input registers - loadData(&data[processed], block_size); - - SHA->SHA_CR = SHA_CR_START; - - // Wait for data ready - while ((SHA->SHA_ISR & SHA_ISR_DATRDY) == 0); - - processed += block_size; - } - - return processed; -} - -static uint32_t processBlockDMA(CRYDriver *cryp, const uint8_t *data,uint32_t len, uint32_t block_size) { - - osalDbgAssert(!((uint32_t) data & (L1_CACHE_BYTES - 1)), "data address not cache aligned"); - -#if 0 - osalDbgAssert(!(block_size & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - uint32_t processed = 0; - - cryp->out = 0; - cryp->in = data; - cryp->len = len; - - cacheCleanRegion((uint8_t *) data, len); - - while ((len - processed) >= block_size) { - - // load data in the sha input registers - // Writing channel - dmaChannelSetSource(cryp->dmatx, &data[processed]); - dmaChannelSetDestination(cryp->dmatx, SHA->SHA_IDATAR); - dmaChannelSetTransactionSize(cryp->dmatx, - (block_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - osalSysLock(); - - dmaChannelEnable(cryp->dmatx); - - osalThreadSuspendS(&cryp->thread); - - osalSysUnlock(); - - processed += block_size; - } - - return processed; -} - -static void update(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size) -{ - uint32_t i; - uint32_t processed; - - //check data from previous update - if (shadata->remaining) { - //complete previous data - uint32_t complement = min_u32(data_size, shadata->block_size - shadata->remaining); - memcpy(&shadata->sha_buffer[shadata->remaining], data, complement); - shadata->remaining += complement; - data += complement; - data_size -= complement; - - //if data is complete process the block - if (shadata->remaining == shadata->block_size) { - if (cryp->config->transfer_mode == TRANSFER_POLLING ) - processBlockPolling(shadata->sha_buffer,shadata->remaining, shadata->block_size); - else - processBlockDMA(cryp, shadata->sha_buffer,shadata->remaining, shadata->block_size); - - shadata->processed += shadata->block_size; - shadata->remaining = 0; - } else { - //complete processing in the next update/ - return; - } - } - - // Process blocks - if (cryp->config->transfer_mode == TRANSFER_POLLING ) - processed = processBlockPolling(data,data_size, shadata->block_size); - else - processed = processBlockDMA(cryp, data,data_size, shadata->block_size); - - shadata->processed += processed; - - //check remaining data and process - shadata->remaining = data_size - processed; - if (shadata->remaining) - { - for (i=0;iremaining;i++) - shadata->sha_buffer[i] = data[processed+i]; - } -} - -static uint32_t fillPadding(struct sha_data *shadata, uint32_t len, uint8_t* buffer,size_t buffer_size) -{ - uint32_t padding_len,k; - - - padding_len = shadPaddedMessSize(shadata->algo, len); - padding_len -= len; - k = padding_len - 9; - - osalDbgAssert( padding_len <= buffer_size,"invalid buffer size"); - - - // Append "1" bit and seven "0" bits to the end of the message - *buffer++ = 0x80; - // Add k "0" bits - memset(buffer, 0, k); - buffer += k; - // length is at the end of message (64-bit) - *buffer++ = 0; - *buffer++ = 0; - *buffer++ = 0; - *buffer++ = (len >> 29) & 0xFF; - *buffer++ = (len >> 21) & 0xFF; - *buffer++ = (len >> 13) & 0xFF; - *buffer++ = (len >> 5) & 0xFF; - *buffer++ = (len << 3) & 0xFF; - return padding_len; -} -#endif /* HAL_USE_CRY */ - -/** @} */ - - diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h deleted file mode 100644 index e112e64e9..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 CRYPTOLIB_LLD_SAMA_SHA_H_ -#define CRYPTOLIB_LLD_SAMA_SHA_H_ - - -cryerror_t sama_sha_lld_init(CRYDriver *cryp, struct sha_data *sha); -cryerror_t sama_sha_lld_update(CRYDriver *cryp, struct sha_data *sha); -cryerror_t sama_sha_lld_final(CRYDriver *cryp, struct sha_data *sha); - - - -#endif /* CRYPTOLIB_LLD_SAMA_SHA_H_ */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c deleted file mode 100644 index bfbfffe7a..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 "hal.h" - -#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) - -#include "sama_crypto_lld.h" -#include "sama_tdes_lld.h" - -enum tdesd_key_mode_t { - TDES_KEY_THREE = 0, TDES_KEY_TWO -}; - -void tdes_set_input(uint32_t* data0, uint32_t* data1) { - TDES->TDES_IDATAR[0] = *data0; - if (data1) - TDES->TDES_IDATAR[1] = *data1; -} - -void tdes_get_output(uint32_t *data0, uint32_t *data1) { - *data0 = TDES->TDES_ODATAR[0]; - if (data1) - *data1 = TDES->TDES_ODATAR[1]; -} - -cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, tdes_config_t *params, - bool encrypt, const uint8_t *data, size_t data_len, uint8_t * out, - const uint8_t *iv) { - - uint32_t mode = 0; - uint32_t i; - uint8_t size = 8; - uint32_t *vectors = (uint32_t *) iv; - - osalMutexLock(&cryp->mutex); - - //soft reset - TDES->TDES_CR = TDES_CR_SWRST; - //configure - if (encrypt) - mode |= TDES_MR_CIPHER_ENCRYPT; - else - mode |= TDES_MR_CIPHER_DECRYPT; - - if (cryp->key0_size == 16) - mode |= (TDES_KEY_TWO << 4); - else - mode |= (TDES_KEY_THREE << 4); - - mode |= TDES_MR_TDESMOD(params->algo); - - mode |= TDES_MR_SMOD_MANUAL_START; - - mode |= TDES_MR_OPMOD(params->mode); - - if (cryp->config != NULL) { - mode |= TDES_MR_CFBS(cryp->config->cfbs); - - if (params->mode == TDES_MODE_CFB) { - if (cryp->config->cfbs == TDES_CFBS_32) - size = 4; - else if (cryp->config->cfbs == TDES_CFBS_16) - size = 2; - else if (cryp->config->cfbs == TDES_CFBS_8) - size = 1; - } - - } - - TDES->TDES_MR = mode; - - //write keys - - TDES->TDES_KEY1WR[0] = cryp->key0_buffer[0]; - TDES->TDES_KEY1WR[1] = cryp->key0_buffer[1]; - - if (cryp->key0_size > 8) { - TDES->TDES_KEY2WR[0] = cryp->key0_buffer[2]; - TDES->TDES_KEY2WR[1] = cryp->key0_buffer[3]; - } else { - TDES->TDES_KEY2WR[0] = 0x0; - TDES->TDES_KEY2WR[1] = 0x0; - } - if (cryp->key0_size > 16) { - TDES->TDES_KEY3WR[0] = cryp->key0_buffer[4]; - TDES->TDES_KEY3WR[1] = cryp->key0_buffer[5]; - } else { - TDES->TDES_KEY3WR[0] = 0x0; - TDES->TDES_KEY3WR[1] = 0x0; - } - /* The Initialization Vector Registers apply to all modes except ECB. */ - if (params->mode != TDES_MODE_ECB && vectors != NULL) { - TDES->TDES_IVR[0] = vectors[0]; - TDES->TDES_IVR[1] = vectors[1]; - } - if (params->algo == TDES_ALGO_XTEA) { - TDES->TDES_XTEA_RNDR = TDES_XTEA_RNDR_XTEA_RNDS(32); - } - - //load 64 bit data size in tdes registers - for (i = 0; i < data_len; i += size) { - if (size == 8) - tdes_set_input((uint32_t *) ((data) + i), - (uint32_t *) ((data) + i + 4)); - else - tdes_set_input((uint32_t *) ((data) + i), NULL); - - //Start TDES - TDES->TDES_CR = TDES_CR_START; - - //check status - while ((TDES->TDES_ISR & TDES_ISR_DATRDY) != TDES_ISR_DATRDY) - ; - - if (size == 8) - tdes_get_output((uint32_t *) ((out) + i), - (uint32_t *) ((out) + i + 4)); - else - tdes_get_output((uint32_t *) ((out) + i), NULL); - } - - osalMutexUnlock(&cryp->mutex); - - - return CRY_NOERROR; -} - -cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, tdes_config_t *params, - bool encrypt, const uint8_t *data, size_t data_len, uint8_t * out, - const uint8_t *iv) { - - osalDbgAssert(!((uint32_t) data & (L1_CACHE_BYTES - 1)), "data address not cache aligned"); - osalDbgAssert(!((uint32_t) out & (L1_CACHE_BYTES - 1)), "out address not cache aligned"); - -#if 0 - osalDbgAssert(!(data_len & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - /* - * If size is not multiple of cache line, clean cache region is required. - * TODO: remove when size assert works - */ - if (data_len & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) out, data_len); - } - - uint32_t mode = 0; - uint32_t *vectors = (uint32_t *) iv; - - osalMutexLock(&cryp->mutex); - - cacheCleanRegion((uint8_t *) data, data_len); - - cryp->out = out; - cryp->in = data; - cryp->len = data_len; - - cryp->dmachunksize = DMA_CHUNK_SIZE_1; - - cryp->dmawith = DMA_DATA_WIDTH_WORD; - - if ((params->mode == TDES_MODE_CFB)) { - if (cryp->config->cfbs == TDES_CFBS_16) - cryp->dmawith = DMA_DATA_WIDTH_HALF_WORD; - if (cryp->config->cfbs == TDES_CFBS_8) - cryp->dmawith = DMA_DATA_WIDTH_BYTE; - } - - cryp->rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_TDES_RX); - - cryp->txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_PROT_SEC | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE(cryp->dmachunksize) | - XDMAC_CC_DWIDTH(cryp->dmawith) | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_TDES_TX); - - dmaChannelSetMode(cryp->dmarx, cryp->rxdmamode); - dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); - - // Writing channel - dmaChannelSetSource(cryp->dmatx, data); - dmaChannelSetDestination(cryp->dmatx, TDES->TDES_IDATAR); - dmaChannelSetTransactionSize(cryp->dmatx, - (data_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - - // Reading channel - dmaChannelSetSource(cryp->dmarx, TDES->TDES_ODATAR); - dmaChannelSetDestination(cryp->dmarx, out); - dmaChannelSetTransactionSize(cryp->dmarx, - (data_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); - - //soft reset - TDES->TDES_CR = TDES_CR_SWRST; - - //configure - if (encrypt) - mode |= TDES_MR_CIPHER_ENCRYPT; - else - mode |= TDES_MR_CIPHER_DECRYPT; - - if (cryp->key0_size == 16) - mode |= (TDES_KEY_TWO << 4); - else - mode |= (TDES_KEY_THREE << 4); - - mode |= TDES_MR_TDESMOD(params->algo); - - mode |= TDES_MR_SMOD_IDATAR0_START; - - mode |= TDES_MR_OPMOD(params->mode); - - if (cryp->config != NULL) { - mode |= TDES_MR_CFBS(cryp->config->cfbs); - } - - TDES->TDES_MR = mode; - - - - //write keys - TDES->TDES_KEY1WR[0] = cryp->key0_buffer[0]; - TDES->TDES_KEY1WR[1] = cryp->key0_buffer[1]; - - if (cryp->key0_size > 8) { - TDES->TDES_KEY2WR[0] = cryp->key0_buffer[2]; - TDES->TDES_KEY2WR[1] = cryp->key0_buffer[3]; - } else { - TDES->TDES_KEY2WR[0] = 0x0; - TDES->TDES_KEY2WR[1] = 0x0; - } - if (cryp->key0_size > 16) { - TDES->TDES_KEY3WR[0] = cryp->key0_buffer[4]; - TDES->TDES_KEY3WR[1] = cryp->key0_buffer[5]; - } else { - TDES->TDES_KEY3WR[0] = 0x0; - TDES->TDES_KEY3WR[1] = 0x0; - } - //initialize vectors registers ( except ECB mode) - if (params->mode != TDES_MODE_ECB && vectors != NULL) { - TDES->TDES_IVR[0] = vectors[0]; - TDES->TDES_IVR[1] = vectors[1]; - } - - - - if (params->algo == TDES_ALGO_XTEA) { - TDES->TDES_XTEA_RNDR = TDES_XTEA_RNDR_XTEA_RNDS(32); - } - -//enable interrutps - TDES->TDES_IER = TDES_IER_DATRDY; - - osalSysLock(); - - dmaChannelEnable(cryp->dmarx); - dmaChannelEnable(cryp->dmatx); - - osalThreadSuspendS(&cryp->thread); - osalSysUnlock(); - - osalMutexUnlock(&cryp->mutex); - - return CRY_NOERROR; -} - -#endif /* HAL_USE_CRY */ - -/** @} */ - diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h deleted file mode 100644 index 7f714f9e0..000000000 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 CRYPTOLIB_LLD_TDES_H_ -#define CRYPTOLIB_LLD_TDES_H_ - - - -typedef enum { - TDES_MODE_ECB = 0, - TDES_MODE_CBC, - TDES_MODE_OFB, - TDES_MODE_CFB -}tdes_mode_t; - - - -typedef enum { - TDES_CFBS_64 = 0, - TDES_CFBS_32, - TDES_CFBS_16, - TDES_CFBS_8 -}tdes_cipher_size_t; - -typedef struct { - tdes_algo_t algo; - tdes_mode_t mode; -}tdes_config_t; - - -extern void sama_tdes_lld_init(CRYDriver *cryp); - -extern cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, - tdes_config_t *params, - bool encrypt, - const uint8_t *data, - size_t data_len, - uint8_t *out, - const uint8_t *iv); -extern cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, - tdes_config_t *params, - bool encrypt, - const uint8_t *data, - size_t data_len, - uint8_t *out, - const uint8_t *iv); - - -#endif /* CRYPTOLIB_LLD_TDES_H_ */ diff --git a/os/hal/ports/SAMA/LLD/DMAv1/driver.mk b/os/hal/ports/SAMA/LLD/DMAv1/driver.mk deleted file mode 100644 index 98442df22..000000000 --- a/os/hal/ports/SAMA/LLD/DMAv1/driver.mk +++ /dev/null @@ -1,2 +0,0 @@ -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/DMAv1 diff --git a/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c b/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c deleted file mode 100644 index fa925e88a..000000000 --- a/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 DMAv1/sama_xdmac.c - * @brief Enhanced DMA helper driver code. - * - * @addtogroup SAMA_DMA - * @details DMA sharing helper driver. In the SAMA the DMA channels are a - * dedicated resource, this driver allows to allocate and free DMA - * channels at runtime. - * @{ - */ - -#include "hal.h" - -/* The following macro is only defined if some driver requiring DMA services - has been enabled.*/ -#if defined(SAMA_DMA_REQUIRED) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -sama_dma_channel_t _sama_dma_channel_t[XDMAC_CHANNELS]; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Get content of Global Status register. - * - * @param[in] xdmacp pointer to DMA controller - * @return XDMAC_GS content of Global Status register - * - * @notapi - */ - #define dmaGetGlobal(xdmacp) xdmacp->XDMAC_GS - -/** - * @brief Get content of Global Interrupt Status register. - * - * @param[in] xdmacp pointer to DMA controller - * @return XDMAC_GIS content of Global Interrupt Status register - * - * @notapi - */ - #define dmaGetGlobalInt(xdmacp) xdmacp->XDMAC_GIS - -/** - * @brief Get content of Channel Interrupt Mask register. - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * @return XDMAC_CIMx content of Channel Interrupt Mask register - * - * @notapi - */ -#define dmaGetChannelIntMask(dmachp) \ - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CIM - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief XDMAC interrupt handler - */ -OSAL_IRQ_HANDLER(dmaHandler) { - - OSAL_IRQ_PROLOGUE(); - -#if SAMA_HAL_IS_SECURE - Xdmac *xdmac = XDMAC1; -#else - Xdmac *xdmac = XDMAC0; -#endif /* SAMA_HAL_IS_SECURE */ - - uint32_t chan, gis; - - /* Read Global Interrupt Status Register */ - gis = dmaGetGlobalInt(xdmac); - - for (chan = 0; gis && (chan < XDMAC_CHANNELS); chan++) { - sama_dma_channel_t *channel = &_sama_dma_channel_t[chan]; - - if (!(gis & (0x1 << chan))) - /* There is no pending interrupt for this channel */ - continue; - gis &= ~(0x1 << chan); - - /** - * if a channel interrupt is enabled and pending, and a callback exists, - * execute it - */ - uint32_t cis = dmaGetChannelInt(channel) & dmaGetChannelIntMask(channel); - if (cis && channel->dma_func) - channel->dma_func(channel->dma_param, cis); - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief SAMA DMA helper initialization. - * - * @init - */ -void dmaInit(void) { - -#if SAMA_HAL_IS_SECURE - Xdmac *xdmac = XDMAC1; - mtxConfigPeriphSecurity(MATRIX0, ID_XDMAC1, SECURE_PER); -#else - Xdmac *xdmac = XDMAC0; -#endif /* SAMA_HAL_IS_SECURE */ - - uint8_t chan; - - for (chan = 0; chan < XDMAC_CHANNELS; chan++) { - sama_dma_channel_t *channel = &_sama_dma_channel_t[chan]; - - /* Initialization of the specific channel */ - channel->xdmac = xdmac; - channel->chid = chan; - channel->state = SAMA_DMA_FREE; - channel->dma_func = NULL; - - /* Clear interrupts */ - dmaGetChannelInt(channel); - } - - /* Setting aic source handler */ -#if SAMA_HAL_IS_SECURE - aicSetSourceHandler(ID_XDMAC1, dmaHandler); -#else - aicSetSourceHandler(ID_XDMAC0, dmaHandler); -#endif /* SAMA_HAL_IS_SECURE */ -} - -/** - * @brief Sets the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmastp pointer to a sama_dma_channel_t structure - * @param[in] size value to be written in the XDMAC_CUBC register - * - * @special - * - */ -void dmaChannelSetTransactionSize(sama_dma_channel_t *dmachp, size_t n) { - -uint32_t i; -uint32_t divisor; - /* Single block single microblock */ - if (n <= XDMAC_MAX_BT_SIZE) { - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(n); - } - /* Single block multiple microblocks */ - else { - /* If n exceeds XDMAC_MAX_BT_SIZE, split the transfer in microblocks */ - for (i = 2; i < XDMAC_MAX_BT_SIZE; i++) { - divisor = XDMAC_MAX_BT_SIZE / i; - if (n % divisor) - continue; - if ((n / divisor) <= (XDMAC_MAX_BLOCK_LEN + 1)) { - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(i); - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CBC = - XDMAC_CBC_BLEN((n / divisor) - 1); - break; - } - } - osalDbgAssert(i != XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size"); - } -} - -/** - * @brief Assigns a DMA channel. - * @details The channel is assigned and, if required, the DMA clock enabled. - * The function also enables the IRQ vector associated to the channel - * and initializes its priority. - * @pre The channel must not be already in use or an error is returned. - * @post The channel is allocated and the default ISR handler redirected - * to the specified function. - * @post The channel ISR vector is enabled and its priority configured. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] priority IRQ priority mask for the DMA stream - * @param[in] func handling function pointer, can be @p NULL - * @param[in] param a parameter to be passed to the handling function - * @return A pointer to sama_dma_channel_t structure if channel is - * assigned or NULL. - * - * @special - */ -sama_dma_channel_t* dmaChannelAllocate(uint32_t priority, - sama_dmaisr_t func, - void *param) { - - sama_dma_channel_t *channel = NULL; - uint8_t chan; - for (chan = 0; chan < XDMAC_CHANNELS; chan++) { - channel = &_sama_dma_channel_t[chan]; - if (channel->state != SAMA_DMA_FREE) { - channel = NULL; - } - else { - break; - } - } - - if (channel != NULL) { - /* Marks the channel as allocated.*/ - channel->state = SAMA_DMA_NOT_FREE; - channel->dma_func = func; - channel->dma_param = param; - - /* Setting AIC and enabling DMA clocks required by the current channel set.*/ -#if SAMA_HAL_IS_SECURE - aicSetSourcePriority(ID_XDMAC1, priority); - aicEnableInt(ID_XDMAC1); - pmcEnableXDMAC1(); -#else - aicSetSourcePriority(ID_XDMAC0, priority); - aicEnableInt(ID_XDMAC0); - pmcEnableXDMAC0(); -#endif /* SAMA_HAL_IS_SECURE */ - - /* Enabling channel's interrupt */ - channel->xdmac->XDMAC_CHID[channel->chid].XDMAC_CIE = XDMAC_CIE_BIE | - XDMAC_CIE_WBIE | - XDMAC_CIE_RBIE | - XDMAC_CIE_ROIE; - channel->xdmac->XDMAC_GIE = XDMAC_GIE_IE0 << (channel->chid); - } - return channel; -} - -/** - * @brief Releases a DMA channel. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post The channel is again available. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * - * @special - */ -void dmaChannelRelease(sama_dma_channel_t *dmachp) { - - osalDbgCheck(dmachp != NULL); - /* Check if the channel is free.*/ - osalDbgAssert(dmachp->state != SAMA_DMA_FREE, - "not allocated"); - - /* Disables channel */ - dmaChannelDisable(dmachp); - - /* Disables interrupt */ - (dmachp)->xdmac->XDMAC_GID = XDMAC_GID_ID0 << ((dmachp)->chid); - - /* Clear dma descriptor */ - (dmachp)->xdmac->XDMAC_CHID[((dmachp)->chid)].XDMAC_CNDA = 0; - (dmachp)->xdmac->XDMAC_CHID[((dmachp)->chid)].XDMAC_CNDC = 0; - - /* Marks the stream as not allocated.*/ - (dmachp)->state = SAMA_DMA_FREE; -} - -#endif /* SAMA_DMA_REQUIRED */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.h b/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.h deleted file mode 100644 index 4e3ccf089..000000000 --- a/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 DMAv1/sama_xdmac.h - * @brief Enhanced-DMA helper driver header. - * - * @addtogroup SAMA_XDMAC - * @{ - */ - -#ifndef SAMA_XDMAC_H -#define SAMA_XDMAC_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief DMA capability. - * @details if @p TRUE then the DMA is able of burst transfers, FIFOs, - * scatter gather and other advanced features. - */ -#define SAMA_XDMAC_ADVANCED TRUE - -/** - * @brief Number of DMA channels. - * @details This is the number of DMA channel for each controller. - */ -#define XDMAC_CHANNELS (XDMACCHID_NUMBER) - -/** - * @brief Max single transfer size. - * @details This is the maximum single transfer size supported. - */ -#define XDMAC_MAX_BT_SIZE 0xFFFFFF - -/** - * @brief Max DMA length of the block. - * @details This is the maximum length of the block supported. - */ -#define XDMAC_MAX_BLOCK_LEN 0xFFF - -/** - * @brief States of the channel. - */ -#define SAMA_DMA_FREE 0U -#define SAMA_DMA_NOT_FREE 1U - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ -/** - * @brief Descriptor Structure mbr Register. - */ -#define XDMA_UBC_UBLEN_Pos 0 -#define XDMA_UBC_UBLEN_Msk (0xffffffu << XDMA_UBC_UBLEN_Pos) -#define XDMA_UBC_UBLEN(value) ((XDMA_UBC_UBLEN_Msk \ - & ((value) << XDMA_UBC_UBLEN_Pos))) -#define XDMA_UBC_NDE (0x1u << 24) -#define XDMA_UBC_NDE_FETCH_DIS (0x0u << 24) -#define XDMA_UBC_NDE_FETCH_EN (0x1u << 24) - -#define XDMA_UBC_NSEN (0x1u << 25) -#define XDMA_UBC_NSEN_UNCHANGED (0x0u << 25) -#define XDMA_UBC_NSEN_UPDATED (0x1u << 25) - -#define XDMA_UBC_NDEN (0x1u << 26) -#define XDMA_UBC_NDEN_UNCHANGED (0x0u << 26) -#define XDMA_UBC_NDEN_UPDATED (0x1u << 26) - -#define XDMA_UBC_NVIEW_Pos 27 -#define XDMA_UBC_NVIEW_Msk (0x3u << XDMA_UBC_NVIEW_Pos) -#define XDMA_UBC_NVIEW_NDV0 (0x0u << XDMA_UBC_NVIEW_Pos) -#define XDMA_UBC_NVIEW_NDV1 (0x1u << XDMA_UBC_NVIEW_Pos) -#define XDMA_UBC_NVIEW_NDV2 (0x2u << XDMA_UBC_NVIEW_Pos) -#define XDMA_UBC_NVIEW_NDV3 (0x3u << XDMA_UBC_NVIEW_Pos) -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ -/** - * @brief Linker List Descriptor view0. - */ -typedef struct { - void *mbr_nda; /* Next Descriptor Address */ - uint32_t mbr_ubc; /* Microblock Control */ - void *mbr_ta; /* Transfer Address */ -}lld_view0; - -/** - * @brief SAMA5D2 DMA ISR function type. - * - * @param[in] p parameter for the registered function - * @param[in] flags content of the CIS register. - */ -typedef void (*sama_dmaisr_t)(void *p, uint32_t flags); - -/** - * @brief SAMA5D2 DMA channel descriptor structure. - */ -typedef struct { - Xdmac *xdmac; /**< @brief Associated DMA - controller. */ - uint8_t chid; /**< @brief ID channel */ - uint8_t state; /**< @brief State channel */ - sama_dmaisr_t dma_func; - void *dma_param; -} sama_dma_channel_t; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @name Macro Functions - * @{ - */ -/** - * @brief Gets content of Channel Interrupt Status register. - * @note Reading interrupt is equivalent to clearing interrupt. - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * @return XDMAC_CISx content of Channel Interrupt Status register - * - * @notapi - */ -#define dmaGetChannelInt(dmachp) \ - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CIS - -/** - * @brief Returns the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaChannelAllocate(). - * @post After use the stream can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a @p sama_dma_channel_t structure - * @return The number of transfers to be performed. - * - * @special - */ -#define dmaChannelGetTransactionSize(dmachp) \ - ((size_t)((dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC)) - -/** - * @brief Associates a source to a DMA channel. - * @note This function can be invoked in both ISR or thread context. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * @param[in] addr value to be written in the SA register - * - * @special - */ -#define dmaChannelSetSource(dmachp, addr) { \ - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CSA = XDMAC_CSA_SA((uint32_t)addr); \ -} - -/** - * @brief Associates a destination to a DMA channel. - * @note This function can be invoked in both ISR or thread context. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * @param[in] addr value to be written in the DA register - * - * @special - */ -#define dmaChannelSetDestination(dmachp, addr) { \ - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CDA = XDMAC_CDA_DA((uint32_t)addr); \ -} - -/** - * @brief Sets the channel mode settings. - * @note This function can be invoked in both ISR or thread context. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * @param[in] mode value to be written in the XDMAC_CC register - * - * @special - */ -#define dmaChannelSetMode(dmachp, mode) { \ - (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CC = mode; \ -} - -/** - * @brief Enables DMA channel. - * @note This function can be invoked in both ISR or thread context. - * The hardware disables a channel on transfer completion by clearing - * bit XDMAC_GS.STx. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * - * @special - */ -#define dmaChannelEnable(dmachp) { \ - (dmachp)->xdmac->XDMAC_GE = (XDMAC_GE_EN0 << ((dmachp)->chid)); \ -} - -/** - * @brief DMA channel disable. - * @details The function disables the specified channel, waits for the disable - * operation to complete and then clears any pending interrupt. - * @note This function can be invoked in both ISR or thread context. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * - * @special - */ -#define dmaChannelDisable(dmachp) { \ - (dmachp)->xdmac->XDMAC_GD = XDMAC_GD_DI0 << ((dmachp)->chid); \ - while ((((dmachp)->xdmac->XDMAC_GS) & (XDMAC_GS_ST0 << (dmachp)->chid)) == 1) { \ - ; \ - } \ - dmaGetChannelInt(dmachp); \ -} - -/** - * @brief Starts a memory to memory operation using the specified channel. - * @note The default transfer data mode is "byte to byte" but it can be - * changed by specifying extra options in the @p mode parameter. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - * @param[in] mode value to be written in the CC register, this value - * is implicitly ORed with: - * - @p XDMAC_CC_TYPE_MEM_TRAN - * - @p XDMAC_CC_SAM_INCREMENTED_AM - * - @p XDMAC_CC_DAM_INCREMENTED_AM - * - @p XDMAC_CC_SWREQ_SWR_CONNECTED - * - @p XDMAC_CC_SIF_AHB_IF0 - * - @p XDMAC_CC_DIF_AHB_IF0 - * - @p XDMAC_GE - * . - * @param[in] src source address - * @param[in] dst destination address - * @param[in] mode transfer's configuration - * @param[in] n number of data units to copy - */ -#define dmaStartMemCopy(dmachp, mode, src, dst, n) { \ - dmaChannelSetSource(dmachp, src); \ - dmaChannelSetDestination(dmachp, dst); \ - dmaChannelSetTransactionSize(dmachp, n); \ - dmaChannelSetMode(dmachp, (mode) | \ - XDMAC_CC_TYPE_MEM_TRAN | XDMAC_CC_SAM_INCREMENTED_AM | \ - XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_SWREQ_SWR_CONNECTED | \ - XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF0); \ - dmaChannelEnable(dmachp); \ -} - -/** - * @brief Polled wait for DMA transfer end. - * @pre The channel must have been allocated using @p dmaChannelAllocate(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a sama_dma_channel_t structure - */ -#define dmaWaitCompletion(dmachp) { \ - (dmachp)->xdmac->XDMAC_GID |= XDMAC_GID_ID0 << ((dmachp)->chid); \ - while ((dmachp)->xdmac->XDMAC_GS & (XDMAC_GS_ST0 << ((dmachp)->chid))) \ - ; \ - dmaGetChannelInt(dmachp); \ -} -/** @} */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern sama_dma_channel_t _sama_dma_channel_t[XDMAC_CHANNELS]; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void dmaInit(void); - void dmaChannelSetTransactionSize(sama_dma_channel_t *dmachp, size_t n); - sama_dma_channel_t* dmaChannelAllocate(uint32_t priority, - sama_dmaisr_t func, - void *param); - void dmaChannelRelease(sama_dma_channel_t *dmachp); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_DMA_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/I2Cv1/driver.mk b/os/hal/ports/SAMA/LLD/I2Cv1/driver.mk deleted file mode 100644 index 2534798aa..000000000 --- a/os/hal/ports/SAMA/LLD/I2Cv1/driver.mk +++ /dev/null @@ -1,21 +0,0 @@ -ifeq ($(USE_HAL_I2C_FALLBACK),yes) - # Fallback SW driver. - ifeq ($(USE_SMART_BUILD),yes) - ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c - endif - else - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c - endif - PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C -else - # Default HW driver. - ifeq ($(USE_SMART_BUILD),yes) - ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c - endif - else - PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c - endif - PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/I2Cv1 -endif diff --git a/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c b/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c deleted file mode 100644 index 490364452..000000000 --- a/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.c +++ /dev/null @@ -1,963 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 I2Cv1/hal_i2c_lld.c - * @brief SAMA I2C subsystem low level driver source. - * - * @addtogroup I2C - * @{ - */ - -#include "hal.h" - -#if HAL_USE_I2C || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/* SAMA5D2 Clock offset. */ -#define TWI_CLK_OFFSET 3 - -/* Mask for 10-bit address. */ -#define TWI_ADDR_MASK_10 0x380 - -/* Mask for 10-bit address case for DADR field. */ -#define TWI_ADDR_10_DADR_MASK 0x78 -#define TWI_ADDR_10_IADR_MASK 0xFF - -/* Mask for internal address check. */ -#define TWI_INTERNAL_ADDR_MASK 0xFF - -/* Mask for TWI errors interrupt. */ -#define TWI_ERROR_MASK (TWI_SR_OVRE | TWI_SR_UNRE | \ - TWI_SR_NACK | TWI_SR_ARBLST | \ - TWI_SR_TOUT | TWI_SR_PECERR) - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ -#if !defined ROUND_INT_DIV -#define ROUND_INT_DIV(n,d) (((n) + ((d)-1)) / (d)) -#endif - -/** - * @brief Enable write protection on TWI registers block. - * - * @param[in] i2cp pointer to a TWI register block - * - * @notapi - */ -#define twiEnableWP(i2cp) { \ - i2cp->TWI_WPMR = TWI_WPMR_WPKEY_PASSWD | TWI_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on TWI registers block. - * - * @param[in] i2cp pointer to a TWI register block - * - * @notapi - */ -#define twiDisableWP(i2cp) { \ - i2cp->TWI_WPMR = TWI_WPMR_WPKEY_PASSWD; \ -} - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief I2C0 driver identifier.*/ -#if SAMA_I2C_USE_TWIHS0 || defined(__DOXYGEN__) -I2CDriver I2CD0; -#endif - -/** @brief I2C1 driver identifier.*/ -#if SAMA_I2C_USE_TWIHS1 || defined(__DOXYGEN__) -I2CDriver I2CD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Read a byte from TWI_RHR register. - * - * @param[in] reg pointer to the target register - * @param[in] value pointer to the transmit variable - * - * @notapi - */ -static inline void i2c_lld_read_byte(volatile const void* reg, uint8_t* value) { - *value = *(volatile const uint8_t*)reg; -} - -/** - * @brief Write a byte to TWI_THR register. - * - * @param[in] reg pointer to the target register - * @param[in] value pointer to the receive variable - * - * @notapi - */ -static inline void i2c_lld_write_byte(volatile void* reg, uint8_t value) { - *(volatile uint8_t*)reg = value; -} - -/** - * @brief Read bytes. - * @note Disables WRITE PROTECTION before using - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static void i2c_lld_read_bytes(I2CDriver *i2cp) { - - if (i2cp->rxbytes == 1) { - - /* Starts and stops the operation for 1 byte read.*/ - i2cp->i2c->TWI_CR = TWI_CR_START | TWI_CR_STOP; - i2cp->i2c->TWI_IER = TWI_IER_TXCOMP; - while ((i2cp->i2c->TWI_SR & TWI_SR_RXRDY) == 0); - - i2c_lld_read_byte(&i2cp->i2c->TWI_RHR, i2cp->rxbuf); - } - - if (i2cp->rxbytes == 2) { - - /* Starts the operation.*/ - i2cp->i2c->TWI_CR = TWI_CR_START; - i2cp->i2c->TWI_IER = TWI_IER_TXCOMP; - while ((i2cp->i2c->TWI_SR & TWI_SR_RXRDY) == 0); - - /* Stops the operation and read penultimate byte. */ - i2cp->i2c->TWI_CR = TWI_CR_STOP; - - i2c_lld_read_byte(&i2cp->i2c->TWI_RHR, &i2cp->rxbuf[0]); - - while ((i2cp->i2c->TWI_SR & TWI_SR_RXRDY) == 0); - - /* Read last byte. */ - i2c_lld_read_byte(&i2cp->i2c->TWI_RHR, &i2cp->rxbuf[1]); - } - - if (i2cp->rxbytes > 2) { - - /* RX DMA setup.*/ - dmaChannelSetDestination(i2cp->dmarx, i2cp->rxbuf); - dmaChannelSetTransactionSize(i2cp->dmarx, i2cp->rxbytes -2); - - /* Starts the operation.*/ - i2cp->i2c->TWI_CR = TWI_CR_START; - - /* Start the DMA. */ - dmaChannelEnable(i2cp->dmarx); - } -} - -/** - * @brief Write bytes. - * @note Disables WRITE PROTECTION before using - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static void i2c_lld_write_bytes(I2CDriver *i2cp) { - - size_t txsize = i2cp->txbytes; - - if (txsize == 1) { - - i2c_lld_write_byte(&i2cp->i2c->TWI_THR, i2cp->txbuf[0]); - - /* Enable TXCOMP interrupt. */ - i2cp->i2c->TWI_IER = TWI_IER_TXCOMP; - - i2cp->i2c->TWI_CR = TWI_CR_STOP; - - /* Starts and stops the operation for 1 byte write.*/ - while ((i2cp->i2c->TWI_SR & TWI_SR_TXRDY) == 0); - } - - if (txsize > 1) { - /* RX DMA setup.*/ - dmaChannelSetSource(i2cp->dmatx, i2cp->txbuf); - dmaChannelSetTransactionSize(i2cp->dmatx, (txsize - 1)); - dmaChannelEnable(i2cp->dmatx); - } -} - -/** - * @brief Set operation mode of I2C hardware. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static void i2c_lld_set_opmode(I2CDriver *i2cp) { - - switch (i2cp->config->op_mode) { - case OPMODE_I2C: - i2cp->i2c->TWI_CR = TWI_CR_SMBDIS; - break; - case OPMODE_SMBUS: - i2cp->i2c->TWI_CR = TWI_CR_SMBEN; - break; - } -} - -/** - * @brief DMA RX end IRQ handler. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] flags pre-shifted content of the ISR register - * - * @notapi - */ -static void i2c_lld_serve_rx_interrupt(I2CDriver *i2cp, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(SAMA_I2C_DMA_ERROR_HOOK) - if ((flags & (XDMAC_CIS_RBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_I2C_DMA_ERROR_HOOK(i2cp); - } -#else - (void)flags; -#endif - - /* DMA channel disable. */ - dmaChannelDisable(i2cp->dmarx); - - /* Cache is enabled */ - cacheInvalidateRegion(i2cp->rxbuf, i2cp->rxbytes - 1); - - /* Wait for RXRDY flag. */ - while ((i2cp->i2c->TWI_SR & TWI_SR_RXRDY) == 0); - - /* Stops the operation and read the last 2 bytes.*/ - i2cp->i2c->TWI_CR = TWI_CR_STOP; - i2c_lld_read_byte(&i2cp->i2c->TWI_RHR, &i2cp->rxbuf[i2cp->rxbytes - 2]); - - /* Wait for the last byte. */ - while ((i2cp->i2c->TWI_SR & TWI_SR_RXRDY) == 0); - - /* Enable TXCOMP interrupt. */ - i2cp->i2c->TWI_IER = TWI_IER_TXCOMP; - - /* Read the last byte. */ - i2c_lld_read_byte(&i2cp->i2c->TWI_RHR, &i2cp->rxbuf[i2cp->rxbytes - 1]); - -} - - -/** - * @brief DMA TX end IRQ handler. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static void i2c_lld_serve_tx_interrupt(I2CDriver *i2cp, uint32_t flags) { - - const uint8_t tx_last_byte = i2cp->txbuf[i2cp->txbytes - 1]; - /* DMA errors handling.*/ -#if defined(SAMA_I2C_DMA_ERROR_HOOK) - if ((flags & (XDMAC_CIS_WBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_I2C_DMA_ERROR_HOOK(i2cp); - } -#else - (void)flags; -#endif - - dmaChannelDisable(i2cp->dmatx); - - /* Wait for the TX ready flag. */ - while ((i2cp->i2c->TWI_SR & TWI_SR_TXRDY) == 0); - - /* Stops the operation and transmit the last byte.*/ - i2cp->i2c->TWI_CR = TWI_CR_STOP; - - i2cp->i2c->TWI_IER = TWI_IER_TXCOMP; - - i2c_lld_write_byte(&i2cp->i2c->TWI_THR, tx_last_byte); -} - -/** - * @brief I2C interrupts handler. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t flags) { - - /* Used only in 1/2 bytes transmissions in order to wake up the thread. */ - if (flags & TWI_SR_TXCOMP) { - _i2c_wakeup_isr(i2cp); - } - - i2cp->errors = I2C_NO_ERROR; - - if (flags & TWI_SR_OVRE) /* Overrun error. */ - i2cp->errors |= I2C_OVERRUN; - - if (flags & TWI_SR_UNRE) /* Underrun error. */ - i2cp->errors |= I2C_OVERRUN; - - if (flags & TWI_SR_NACK) { /* Acknowledge fail. */ - i2cp->i2c->TWI_CR = TWI_CR_STOP; /* Setting stop bit. */ - i2cp->errors |= I2C_ACK_FAILURE; - } - - if (flags & TWI_SR_ARBLST) /* Arbitration lost. */ - i2cp->errors |= I2C_ARBITRATION_LOST; - - if (flags & TWI_SR_TOUT) /* SMBus Timeout. */ - i2cp->errors |= I2C_TIMEOUT; - - if (flags & TWI_SR_PECERR) /* PEC error. */ - i2cp->errors |= I2C_PEC_ERROR; - - /* If some error has been identified then sends wakes the waiting thread.*/ - if (i2cp->errors != I2C_NO_ERROR) - _i2c_wakeup_error_isr(i2cp); -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if SAMA_I2C_USE_TWIHS0 || defined(__DOXYGEN__) -/** - * @brief TWIHS0 interrupt handler. - * - * @notapi - */ -OSAL_IRQ_HANDLER(SAMA_TWIHS0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr = I2CD0.i2c->TWI_SR; - - I2CD0.i2c->TWI_IDR = TWI_IDR_TXCOMP; - - i2c_lld_serve_interrupt(&I2CD0, sr); - aicAckInt(); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_I2C_USE_TWIHS0 */ - -#if SAMA_I2C_USE_TWIHS1 || defined(__DOXYGEN__) -/** - * @brief TWIHS1 interrupt handler. - * - * @notapi - */ -OSAL_IRQ_HANDLER(SAMA_TWIHS1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr = I2CD1.i2c->TWI_SR; - - I2CD1.i2c->TWI_IDR = TWI_IDR_TXCOMP; - - i2c_lld_serve_interrupt(&I2CD1, sr); - aicAckInt(); - - OSAL_IRQ_EPILOGUE(); -} - -#endif /* SAMA_I2C_USE_TWIHS1 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level I2C driver initialization. - * - * @notapi - */ -void i2c_lld_init(void) { - -#if SAMA_I2C_USE_TWIHS0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TWIHS0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - i2cObjectInit(&I2CD0); - I2CD0.thread = NULL; - I2CD0.i2c = TWIHS0; - I2CD0.dmarx = NULL; - I2CD0.dmatx = NULL; - I2CD0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_TWIHS0_RX); - I2CD0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_TWIHS0_TX); -#endif /* SAMA_I2C_USE_TWIHS0 */ - -#if SAMA_I2C_USE_TWIHS1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TWIHS1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - i2cObjectInit(&I2CD1); - I2CD1.thread = NULL; - I2CD1.i2c = TWIHS1; - I2CD1.dmarx = NULL; - I2CD1.dmatx = NULL; - I2CD1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_TWIHS1_RX); - I2CD1.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_TWIHS1_TX); -#endif /* SAMA_I2C_USE_TWIHS1 */ -} - -/** - * @brief Configures and activates the I2C peripheral. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -void i2c_lld_start(I2CDriver *i2cp) { - - uint32_t ck_div, clh_div, hold; - - /* If in stopped state then enables the I2C and DMA clocks.*/ - if (i2cp->state == I2C_STOP) { - -#if SAMA_I2C_USE_TWIHS0 - if (&I2CD0 == i2cp) { - - i2cp->dmarx = dmaChannelAllocate(SAMA_I2C_TWIHS0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)i2c_lld_serve_rx_interrupt, - (void *)i2cp); - osalDbgAssert(i2cp->dmarx != NULL, "no channel allocated"); - - i2cp->dmatx = dmaChannelAllocate(SAMA_I2C_TWIHS0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)i2c_lld_serve_tx_interrupt, - (void *)i2cp); - osalDbgAssert(i2cp->dmatx != NULL, "no channel allocated"); - - pmcEnableTWIHS0(); - /* To prevent spurious interrupt */ - aicSetIntSourceType(ID_TWIHS0, EXT_NEGATIVE_EDGE); - aicSetSourcePriority(ID_TWIHS0, SAMA_I2C_TWIHS0_IRQ_PRIORITY); - aicSetSourceHandler(ID_TWIHS0, SAMA_TWIHS0_HANDLER); - aicEnableInt(ID_TWIHS0); - } -#endif /* SAMA_I2C_USE_TWIHS0 */ - -#if SAMA_I2C_USE_TWIHS1 - if (&I2CD1 == i2cp) { - - i2cp->dmarx = dmaChannelAllocate(SAMA_I2C_TWIHS1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)i2c_lld_serve_rx_interrupt, - (void *)i2cp); - osalDbgAssert(i2cp->dmarx != NULL, "no channel allocated"); - - i2cp->dmatx = dmaChannelAllocate(SAMA_I2C_TWIHS1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)i2c_lld_serve_tx_interrupt, - (void *)i2cp); - osalDbgAssert(i2cp->dmatx != NULL, "no channel allocated"); - - pmcEnableTWIHS1(); - /* To prevent spurious interrupt */ - aicSetIntSourceType(ID_TWIHS1, EXT_NEGATIVE_EDGE); - aicSetSourcePriority(ID_TWIHS1, SAMA_I2C_TWIHS1_IRQ_PRIORITY); - aicSetSourceHandler(ID_TWIHS1, SAMA_TWIHS1_HANDLER); - aicEnableInt(ID_TWIHS1); - } -#endif /* SAMA_I2C_USE_TWIHS1 */ - } - - /* Set mode */ - dmaChannelSetMode(i2cp->dmarx, i2cp->rxdmamode); - dmaChannelSetSource(i2cp->dmarx, &i2cp->i2c->TWI_RHR); - - dmaChannelSetMode(i2cp->dmatx, i2cp->txdmamode); - dmaChannelSetDestination(i2cp->dmatx, &i2cp->i2c->TWI_THR); - - /* Disable write protection. */ - twiDisableWP(i2cp->i2c); - - /* TWI software reset */ - i2cp->i2c->TWI_CR = TWI_CR_SWRST; - - /* TWI set operation mode. */ - i2c_lld_set_opmode(i2cp); - - /* Configure dummy slave address */ - i2cp->i2c->TWI_MMR = 0; - - /* Compute clock */ - for (ck_div = 0; ck_div < 7; ck_div++) { - clh_div = ((SAMA_TWIHSxCLK / i2cp->config->clock_speed) - 2 * (TWI_CLK_OFFSET)) >> ck_div; - if (clh_div <= 511) { - break; - } - } - - /* Compute holding time (I2C spec requires 300ns) */ - hold = TWI_CWGR_HOLD(ROUND_INT_DIV((uint32_t)(0.3 * SAMA_TWIHSxCLK), 1000000) - 3); - - /* Configure clock */ - i2cp->i2c->TWI_CWGR = TWI_CWGR_CKDIV(ck_div) | - TWI_CWGR_CHDIV(clh_div >> 1) | - TWI_CWGR_CLDIV(clh_div >> 1) | - hold; - - /* Clear status flag */ - i2cp->i2c->TWI_SR; - - /* Enable Interrupt. */ - i2cp->i2c->TWI_IER = TWI_ERROR_MASK; - - /* Set master mode */ - i2cp->i2c->TWI_CR = TWI_CR_SVDIS; - i2cp->i2c->TWI_CR = TWI_CR_MSEN; - - /* Enable write protection. */ - twiEnableWP(i2cp->i2c); -} - -/** - * @brief Deactivates the I2C peripheral. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -void i2c_lld_stop(I2CDriver *i2cp) { - - /* If not in stopped state then disables the I2C clock.*/ - if (i2cp->state != I2C_STOP) { - - /* Disable write protection. */ - twiDisableWP(i2cp->i2c); - - /* I2C disable.*/ - - /* Disable interrupts. */ - i2cp->i2c->TWI_IDR = TWI_ERROR_MASK; - - /* TWI software reset. */ - i2cp->i2c->TWI_CR = TWI_CR_SWRST; - i2cp->i2c->TWI_MMR = 0; - - /* DMA channel release. */ - dmaChannelRelease(i2cp->dmatx); - dmaChannelRelease(i2cp->dmarx); - -#if SAMA_I2C_USE_TWIHS0 - if (&I2CD0 == i2cp) { - pmcDisableTWIHS0(); - } -#endif - -#if SAMA_I2C_USE_TWIHS1 - if (&I2CD1 == i2cp) { - pmcDisableTWIHS1(); - } -#endif - - /* Enable write protection. */ - twiEnableWP(i2cp->i2c); - } - - i2cp->txbuf = NULL; - i2cp->rxbuf = NULL; - i2cp->txbytes = 0; - i2cp->rxbytes = 0; -} - -/** - * @brief Receives data via the I2C bus as master. - * @details - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] addr slave device address - * @param[out] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_INFINITE no timeout. - * . - * @return The operation status. - * @retval MSG_OK if the function succeeded. - * @retval MSG_RESET if one or more I2C errors occurred, the errors can - * be retrieved using @p i2cGetErrors(). - * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a - * timeout the driver must be stopped and restarted - * because the bus is in an uncertain state. - * - * @notapi - */ -msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, - uint8_t *rxbuf, size_t rxbytes, - sysinterval_t timeout) { - - osalDbgAssert(!((uint32_t) rxbuf & (L1_CACHE_BYTES - 1)), "rxbuf address not cache aligned"); - -#if 0 - osalDbgAssert(!(rxbytes & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - i2cp->txbuf = NULL; - i2cp->rxbuf = rxbuf; - i2cp->txbytes = 0; - i2cp->rxbytes = rxbytes; - - /* - * If size is not multiple of cache line, clean cache region is required. - * TODO: remove when size assert works - */ - if (rxbytes & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) rxbuf, rxbytes); - } - - systime_t start, end; - - /* Resetting error flags for this transfer.*/ - i2cp->errors = I2C_NO_ERROR; - - /* Disable write protection. */ - twiDisableWP(i2cp->i2c); - - /* Compute device address and/or internal address. */ - i2cp->i2c->TWI_MMR = 0; - - if ((addr & TWI_ADDR_MASK_10) != 0) { - /* 10-bit address. */ - if (i2cp->config->op_mode == OPMODE_I2C) { - - /* Store 2 slave device address MSB bits in MMR_DADR with 11110 mask. Configure number of internal slave address bytes in MMR_IADRSZ as 1. */ - i2cp->i2c->TWI_MMR = TWI_MMR_DADR((addr >> 8) | TWI_ADDR_10_DADR_MASK) | - TWI_MMR_IADRSZ_1_BYTE | TWI_MMR_MREAD; - i2cp->i2c->TWI_IADR = TWI_ADDR_10_IADR_MASK & addr; - - } else if (i2cp->config->op_mode == OPMODE_SMBUS) - osalDbgAssert((addr & TWI_ADDR_MASK_10) != 0, "10-bit address not supported in SMBus mode"); - - } else { - /* 7-bit address. */ - /* Store slave device address in MMR_DADR. */ - i2cp->i2c->TWI_MMR |= TWI_MMR_DADR(addr); - - /* Configure read direction. */ - i2cp->i2c->TWI_MMR |= TWI_MMR_MREAD; - } - /* Releases the lock from high level driver.*/ - osalSysUnlock(); - - /* Calculating the time window for the timeout on the busy bus condition.*/ - start = osalOsGetSystemTimeX(); - end = osalTimeAddX(start, OSAL_MS2I(SAMA_I2C_BUSY_TIMEOUT)); - - /* Waits until BUSY flag is reset or, alternatively, for a timeout - condition.*/ - while (true) { - osalSysLock(); - - /* If the bus is not busy then the operation can continue, note, the - loop is exited in the locked state.*/ - if (i2cp->i2c->TWI_SR & (TWI_SR_TXCOMP | TWI_SR_RXRDY)) - break; - - /* If the system time went outside the allowed window then a timeout - condition is returned.*/ - if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) - return MSG_TIMEOUT; - - osalSysUnlock(); - } - - i2c_lld_read_bytes(i2cp); - - /* Enable write protection. */ - twiEnableWP(i2cp->i2c); - - /* Waits for the operation completion or a timeout.*/ - return osalThreadSuspendTimeoutS(&i2cp->thread, timeout); -} - -/** - * @brief Transmits data via the I2C bus as master. - * @details When performing reading through write you can not write more than - * 3 bytes of data to I2C slave. This is SAMA platform limitation. - * Internal address bytes must be set in txbuf from LSB (position 0 of the buffer) to MSB - * (position 1 or 2 of the buffer depending from the number of internal address bytes. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * @param[in] addr slave device address - * @param[in] txbuf pointer to the transmit buffer - * @param[in] txbytes number of bytes to be transmitted - * @param[out] rxbuf pointer to the receive buffer - * @param[in] rxbytes number of bytes to be received - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_INFINITE no timeout. - * . - * @return The operation status. - * @retval MSG_OK if the function succeeded. - * @retval MSG_RESET if one or more I2C errors occurred, the errors can - * be retrieved using @p i2cGetErrors(). - * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a - * timeout the driver must be stopped and restarted - * because the bus is in an uncertain state. - * - * @notapi - */ -msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, - const uint8_t *txbuf, size_t txbytes, - uint8_t *rxbuf, size_t rxbytes, - sysinterval_t timeout) { - - osalDbgAssert(!((uint32_t) txbuf & (L1_CACHE_BYTES - 1)), "txbuf address not cache aligned"); - osalDbgAssert(!((uint32_t) rxbuf & (L1_CACHE_BYTES - 1)), "rxbuf address not cache aligned"); - -#if 0 - osalDbgAssert(!(rxbytes & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - i2cp->txbuf = txbuf; - i2cp->rxbuf = rxbuf; - i2cp->txbytes = txbytes; - i2cp->rxbytes = rxbytes; - - /* Cache is enabled */ - cacheCleanRegion((uint8_t *)i2cp->txbuf, txbytes); - - /* - * If size is not multiple of cache line, clean cache region is required. - * TODO: remove when size assert works - */ - if (rxbytes & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) rxbuf, rxbytes); - } - - systime_t start, end; - - /* Resetting error flags for this transfer.*/ - i2cp->errors = I2C_NO_ERROR; - - /* Disable write protection. */ - twiDisableWP(i2cp->i2c); - - /* prepare to read through write operation */ - if (rxbytes > 0){ - - osalDbgAssert(txbytes <= 3, "Number of internal address bytes not supported. Max number of internal address bytes is 3."); - - i2cp->i2c->TWI_MMR = 0; - - /* Compute slave address and internal addresses. */ - - /* Internal address of I2C slave was set in special Atmel registers. - * Now we must call read function. The I2C cell automatically sends - * bytes from IADR register to bus and issues repeated start. */ - - if ((addr & TWI_ADDR_MASK_10) != 0) { - /* 10-bit address. */ - if (i2cp->config->op_mode == OPMODE_I2C) { - - uint16_t mem_addr = 0; - - osalDbgAssert(txbytes <= 2, "Number of internal address bytes not supported"); - - /* Store 2 slave device address MSB bits in MMR_DADR with 11110 mask. Configure number of internal slave address bytes in - * MMR_IADRSZ as 1 + slave internal addresses. */ - i2cp->i2c->TWI_MMR = TWI_MMR_DADR((addr >> 8) | TWI_ADDR_10_DADR_MASK) | - TWI_MMR_IADRSZ(txbytes + 1); - - if(txbytes == 1) - mem_addr = i2cp->txbuf[0]; - - else if(txbytes == 2) - mem_addr = i2cp->txbuf[0] | (i2cp->txbuf[1] << 8); - - /* Store the rest of the 10-bit address in IADR register. Also store the internal slave address bytes. */ - i2cp->i2c->TWI_IADR = (TWI_ADDR_10_IADR_MASK & addr) | (mem_addr << 8); - - } else if (i2cp->config->op_mode == OPMODE_SMBUS) - osalDbgAssert((addr & TWI_ADDR_MASK_10) != 0, "10-bit address not supported in SMBus mode"); - - } else { - /* 7-bit address. */ - i2cp->i2c->TWI_MMR |= txbytes << 8; - - /* Store internal slave address in TWI_IADR registers */ - i2cp->i2c->TWI_IADR = 0; - while (txbytes > 0){ - i2cp->i2c->TWI_IADR = (i2cp->i2c->TWI_IADR << 8); - i2cp->i2c->TWI_IADR |= *(txbuf++); - txbytes--; - } - /* Store slave device address in MMR_DADR. */ - i2cp->i2c->TWI_MMR |= TWI_MMR_DADR(addr); - } - - #if 0 - osalDbgAssert(!(rxbytes & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); - #endif - - /* Configure read direction. */ - i2cp->i2c->TWI_MMR |= TWI_MMR_MREAD; - - /* Releases the lock from high level driver.*/ - osalSysUnlock(); - - /* Calculating the time window for the timeout on the busy bus condition.*/ - start = osalOsGetSystemTimeX(); - end = osalTimeAddX(start, OSAL_MS2I(SAMA_I2C_BUSY_TIMEOUT)); - - /* Waits until BUSY flag is reset or, alternatively, for a timeout - condition.*/ - while (true) { - osalSysLock(); - - /* If the bus is not busy then the operation can continue, note, the - loop is exited in the locked state.*/ - if (i2cp->i2c->TWI_SR & (TWI_SR_TXCOMP | TWI_SR_RXRDY)) - break; - - /* If the system time went outside the allowed window then a timeout - condition is returned.*/ - if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) - return MSG_TIMEOUT; - - osalSysUnlock(); - } - - i2c_lld_read_bytes(i2cp); - - /* Enable write protection. */ - twiEnableWP(i2cp->i2c); - - /* Waits for the operation completion or a timeout.*/ - return osalThreadSuspendTimeoutS(&i2cp->thread, timeout); - - } else { - /* Compute device slave address. Internal slave address are sent as data. */ - - i2cp->i2c->TWI_MMR = 0; - - if ((addr & TWI_ADDR_MASK_10) != 0) { - /* 10-bit address. */ - if (i2cp->config->op_mode == OPMODE_I2C) { - - /* Store 2 slave device address MSB bits in MMR_DADR with 11110 mask. Configure number of internal slave address bytes in MMR_IADRSZ as 1. */ - i2cp->i2c->TWI_MMR = TWI_MMR_DADR((addr >> 8) | TWI_ADDR_10_DADR_MASK) | - TWI_MMR_IADRSZ_1_BYTE; - i2cp->i2c->TWI_IADR = TWI_ADDR_10_IADR_MASK & addr; - - } else if (i2cp->config->op_mode == OPMODE_SMBUS) - osalDbgAssert((addr & TWI_ADDR_MASK_10) != 0, "10-bit address not supported in SMBus mode"); - - } else { - /* 7-bit address. */ - /* Store slave device address in MMR_DADR. */ - i2cp->i2c->TWI_MMR |= TWI_MMR_DADR(addr); - } - - /* Releases the lock from high level driver.*/ - osalSysUnlock(); - - /* Calculating the time window for the timeout on the busy bus condition.*/ - start = osalOsGetSystemTimeX(); - end = osalTimeAddX(start, OSAL_MS2I(SAMA_I2C_BUSY_TIMEOUT)); - - /* Waits until BUSY flag is reset or, alternatively, for a timeout - condition.*/ - while (true) { - osalSysLock(); - - /* If the bus is not busy then the operation can continue, note, the - loop is exited in the locked state.*/ - if (i2cp->i2c->TWI_SR & (TWI_SR_TXCOMP | TWI_SR_RXRDY)) - break; - - /* If the system time went outside the allowed window then a timeout - condition is returned.*/ - if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) - return MSG_TIMEOUT; - - osalSysUnlock(); - } - - i2c_lld_write_bytes(i2cp); - - /* Enable write protection. */ - twiEnableWP(i2cp->i2c); - - /* Waits for the operation completion or a timeout.*/ - return osalThreadSuspendTimeoutS(&i2cp->thread, timeout); - } -} - -#endif /* HAL_USE_I2C */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.h b/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.h deleted file mode 100644 index 1d3538852..000000000 --- a/os/hal/ports/SAMA/LLD/I2Cv1/hal_i2c_lld.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 I2Cv1/hal_i2c_lld.h - * @brief SAMA I2C subsystem low level driver header. - * - * @addtogroup I2C - * @{ - */ - -#ifndef HAL_I2C_LLD_H -#define HAL_I2C_LLD_H - -#if HAL_USE_I2C || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief I2C0 driver enable switch. - * @details If set to @p TRUE the support for TWIHS0 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_I2C_USE_TWIHS0) || defined(__DOXYGEN__) -#define SAMA_I2C_USE_TWIHS0 FALSE -#endif - -/** - * @brief I2C1 driver enable switch. - * @details If set to @p TRUE the support for TWIHS1 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_I2C_USE_TWIHS1) || defined(__DOXYGEN__) -#define SAMA_I2C_USE_TWIHS1 FALSE -#endif - -/** - * @brief I2C timeout on busy condition in milliseconds. - */ -#if !defined(SAMA_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__) -#define SAMA_I2C_BUSY_TIMEOUT 50 -#endif - -/** - * @brief I2C0 interrupt priority level setting. - */ -#if !defined(SAMA_I2C_TWIHS0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_I2C_TWIHS0_IRQ_PRIORITY 6 -#endif - -/** - * @brief I2C1 interrupt priority level setting. - */ -#if !defined(SAMA_I2C_TWIHS1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_I2C_TWIHS1_IRQ_PRIORITY 6 -#endif - -/** -* @brief I2C0 DMA IRQ priority (0..7|lowest..highest). -* @note The priority level is used for both the TX and RX DMA channels. -*/ -#if !defined(SAMA_I2C_TWIHS0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_I2C_TWIHS0_DMA_IRQ_PRIORITY 6 -#endif - -/** -* @brief I2C1 DMA IRQ priority (0..7|lowest..highest). -* @note The priority level is used for both the TX and RX DMA streams. -*/ -#if !defined(SAMA_I2C_TWIHS1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_I2C_TWIHS1_DMA_IRQ_PRIORITY 6 -#endif - -/** - * @brief I2C DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(SAMA_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define SAMA_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") -#endif - -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/** @brief error checks */ - -#if !SAMA_I2C_USE_TWIHS0 && !SAMA_I2C_USE_TWIHS1 -#error "I2C driver activated but no TWIHS peripheral assigned" -#endif - -#if !defined(SAMA_DMA_REQUIRED) -#define SAMA_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type representing an I2C address. - */ -typedef uint32_t i2caddr_t; - -/** - * @brief Type of I2C driver condition flags. - */ -typedef uint32_t i2cflags_t; - -/** - * @brief Supported modes for the I2C bus. - */ -typedef enum { - OPMODE_I2C = 1, - OPMODE_SMBUS = 2, -} i2copmode_t; - -/** - * @brief Type of I2C driver configuration structure. - */ -typedef struct { - /* End of the mandatory fields.*/ - i2copmode_t op_mode; /**< @brief Specifies the I2C mode. */ - uint32_t clock_speed; /**< @brief Specifies the clock frequency. - @note Must be set to a value lower - than 400kHz. */ -} I2CConfig; - -/** - * @brief Type of a structure representing an I2C driver. - */ -typedef struct I2CDriver I2CDriver; - -/** - * @brief Structure representing an I2C driver. - */ -struct I2CDriver { - /** - * @brief Driver state. - */ - i2cstate_t state; - /** - * @brief Current configuration data. - */ - const I2CConfig *config; - /** - * @brief Error flags. - */ - i2cflags_t errors; -#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) - /** - * @brief Mutex protecting the bus. - */ - mutex_t mutex; -#endif /* I2C_USE_MUTUAL_EXCLUSION */ -#if defined(I2C_DRIVER_EXT_FIELDS) - I2C_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ - /** - * @brief Thread waiting for I/O completion. - */ - thread_reference_t thread; - /** - * @brief Number of bytes in TX phase. - */ - size_t txbytes; - /** - * @brief Number of bytes in RX phase. - */ - size_t rxbytes; - /** - * @brief Pointer to the TX buffer location. - */ - const uint8_t *txbuf; - /** - * @brief Pointer to the RX buffer location. - */ - uint8_t *rxbuf; - /** - * @brief Receive DMA stream. - */ - sama_dma_channel_t *dmarx; - /** - * @brief Transmit DMA stream. - */ - sama_dma_channel_t *dmatx; - /** - * @brief RX DMA mode bit mask. - */ - uint32_t rxdmamode; - /** - * @brief TX DMA mode bit mask. - */ - uint32_t txdmamode; - /** - * @brief Pointer to the TWIHSx registers block. - */ - Twi *i2c; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Get errors from I2C driver. - * - * @param[in] i2cp pointer to the @p I2CDriver object - * - * @notapi - */ -#define i2c_lld_get_errors(i2cp) ((i2cp)->errors) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -#if SAMA_I2C_USE_TWIHS0 -extern I2CDriver I2CD0; -#endif - -#if SAMA_I2C_USE_TWIHS1 -extern I2CDriver I2CD1; -#endif - -#endif /* !defined(__DOXYGEN__) */ - -#ifdef __cplusplus -extern "C" { -#endif - void i2c_lld_init(void); - void i2c_lld_start(I2CDriver *i2cp); - void i2c_lld_stop(I2CDriver *i2cp); - msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, - const uint8_t *txbuf, size_t txbytes, - uint8_t *rxbuf, size_t rxbytes, - sysinterval_t timeout); - msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, - uint8_t *rxbuf, size_t rxbytes, - sysinterval_t timeout); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_I2C */ - -#endif /* HAL_I2C_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/MACv1/driver.mk b/os/hal/ports/SAMA/LLD/MACv1/driver.mk deleted file mode 100644 index 2d9c51db8..000000000 --- a/os/hal/ports/SAMA/LLD/MACv1/driver.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_MAC TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c -endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/MACv1 diff --git a/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c b/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c deleted file mode 100644 index 86edb1877..000000000 --- a/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.c +++ /dev/null @@ -1,852 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 MACv1/hal_mac_lld.c - * @brief SAMA low level MAC driver code. - * - * @addtogroup MAC - * @{ - */ - -#include - -#include "hal.h" - -#if HAL_USE_MAC || defined(__DOXYGEN__) - -#include "hal_mii.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -/* - * @brief Buffer size. - */ -#define BUFFER_SIZE ((((SAMA_MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4) - -/* - * @brief NO CACHE attribute - */ -#if !defined(NO_CACHE) -#define NO_CACHE __attribute__((section (".nocache"))) -#endif - -/* MII divider optimal value.*/ -#if (SAMA_GMAC0CLK <= 20000000) -#define GMAC_CLK GMAC_NCFGR_CLK_MCK_8 -#elif (SAMA_GMAC0CLK <= 40000000) -#define GMAC_CLK GMAC_NCFGR_CLK_MCK_16 -#elif (SAMA_GMAC0CLK <= 80000000) -#define GMAC_CLK GMAC_NCFGR_CLK_MCK_32 -#elif (SAMA_GMAC0CLK <= 120000000) -#define GMAC_CLK GMAC_NCFGR_CLK_MCK_48 -#elif (SAMA_GMAC0CLK <= 160000000) -#define GMAC_CLK GMAC_NCFGR_CLK_MCK_64 -#elif (SAMA_GMAC0CLK <= 240000000) -#define GMAC_CLK GMAC_NCFGR_CLK_MCK_96 -#else -#error "MCK too high, cannot configure MDC clock" -#endif - -/* - * BV1000GT boards use phy address 0 - */ -#if defined(BOARD_ATSAM5D28_XULT) -#define BOARD_PHY_ADDRESS 0 -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -/** - * @brief Ethernet driver 0. - */ -MACDriver ETHD0; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -static const uint8_t default_mac_address[] = {0x54, 0x54, 0x08, 0x34, 0x1f, 0x3a}; - -/* - * In terms of AMBA AHB operation, the descriptors are read from memory using - * a single 32-bit AHB access. The descriptors should be aligned at 32-bit - * boundaries and the descriptors are written to using two individual non - * sequential accesses. - */ - -/* Rx descriptor list */ -NO_CACHE ALIGNED_VAR(4) -static sama_eth_rx_descriptor_t __eth_rd[SAMA_MAC_RECEIVE_BUFFERS]; - -/* Tx descriptor list */ -NO_CACHE ALIGNED_VAR(4) -static sama_eth_tx_descriptor_t __eth_td[SAMA_MAC_TRANSMIT_BUFFERS]; -NO_CACHE ALIGNED_VAR(4) -static sama_eth_tx_descriptor_t __eth_td1[1]; -NO_CACHE ALIGNED_VAR(4) -static sama_eth_tx_descriptor_t __eth_td2[1]; - -NO_CACHE -static uint32_t __eth_rb[SAMA_MAC_RECEIVE_BUFFERS][BUFFER_SIZE]; -NO_CACHE -static uint32_t __eth_tb[SAMA_MAC_TRANSMIT_BUFFERS][BUFFER_SIZE]; - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ -/** - * @brief Waits for phy management logic idle. - * - * @notapi - */ -#define phyWaitIdle() { \ - while ((GMAC0->GMAC_NSR & GMAC_NSR_IDLE) == 0) { \ - ; \ - } \ -} - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Writes a PHY register. - * - * @param[in] macp pointer to the @p MACDriver object - * @param[in] reg_addr register address - * @param[in] value new register value - * - * @notapi - */ -void mii_write(MACDriver *macp, uint32_t reg_addr, uint32_t value) { - - phyWaitIdle(); - - /* Write maintenance register (Clause 22) */ - GMAC0->GMAC_MAN = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2) | - GMAC_MAN_PHYA(macp->phyaddr) | GMAC_MAN_REGA(reg_addr) | - GMAC_MAN_DATA(value); - phyWaitIdle(); -} - -/** - * @brief Reads a PHY register. - * - * @param[in] macp pointer to the @p MACDriver object - * @param[in] reg_addr register address - * - * @return The PHY register content. - * - * @notapi - */ -uint32_t mii_read(MACDriver *macp, uint32_t reg_addr) { - - phyWaitIdle(); - - /* Read maintenance register */ - GMAC0->GMAC_MAN = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2) | - GMAC_MAN_PHYA(macp->phyaddr) | GMAC_MAN_REGA(reg_addr); - phyWaitIdle(); - - return (uint32_t) ((GMAC0->GMAC_MAN) & GMAC_MAN_DATA_Msk >> GMAC_MAN_DATA_Pos); -} - -#if !defined(BOARD_PHY_ADDRESS) -/** - * @brief PHY address detection. - * - * @param[in] macp pointer to the @p MACDriver object - */ -static void mii_find_phy(MACDriver *macp) { - uint32_t i; - -#if SAMA_MAC_PHY_TIMEOUT > 0 - unsigned n = SAMA_MAC_PHY_TIMEOUT; - do { -#endif - for (i = 1U; i < 31U; i++) { - macp->phyaddr = i; - if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16U)) && - ((mii_read(macp, MII_PHYSID2) & 0xFFF0U) == (BOARD_PHY_ID & 0xFFF0U))) { - return; - } - } -#if SAMA_MAC_PHY_TIMEOUT > 0 - n--; - } while (n > 0U); -#endif - macp->phyaddr = 0; - return; - /* Wrong or defective board.*/ - osalSysHalt("MAC failure"); -} -#endif - -/** - * @brief MAC address setup. - * - * @param[in] p pointer to a six bytes buffer containing the MAC - * address - */ -static void mac_lld_set_address(const uint8_t *p) { - - /* MAC address configuration, only a single address comparator is used, - hash table not used.*/ - GMAC0->GMAC_SA[0].GMAC_SAB = (p[3] << 24) | (p[2] << 16) | - (p[1] << 8) | p[0]; - GMAC0->GMAC_SA[0].GMAC_SAT = (p[5] << 8) | p[4]; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -OSAL_IRQ_HANDLER(SAMA_ETH_HANDLER) { - uint32_t isr; - uint32_t rsr; - uint32_t tsr; - - OSAL_IRQ_PROLOGUE(); - - isr = GMAC0->GMAC_ISR; - rsr = GMAC0->GMAC_RSR; - tsr = GMAC0->GMAC_TSR; - - if (isr & GMAC_ISR_RCOMP) { - /* Data Received.*/ - osalSysLockFromISR(); - /* Clear Status Register */ - GMAC0->GMAC_RSR = rsr; - osalThreadDequeueAllI(ÐD0.rdqueue, MSG_RESET); -#if MAC_USE_EVENTS - osalEventBroadcastFlagsI(ÐD0.rdevent, 0); -#endif - osalSysUnlockFromISR(); - } - - if (isr & GMAC_ISR_TCOMP) { - /* Data Transmitted.*/ - osalSysLockFromISR(); - /* Clear Status Register */ - GMAC0->GMAC_TSR = tsr; - osalThreadDequeueAllI(ÐD0.tdqueue, MSG_RESET); - osalSysUnlockFromISR(); - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level MAC initialization. - * - * @notapi - */ -void mac_lld_init(void) { - - unsigned i; - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_GMAC0, SECURE_PER); - mtxConfigPeriphSecurity(MATRIX1, ID_GMAC0_Q1, SECURE_PER); - mtxConfigPeriphSecurity(MATRIX1, ID_GMAC0_Q2, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - macObjectInit(ÐD0); - ETHD0.link_up = false; - - /* Descriptor tables are initialized in chained mode, note that the status - word is not initialized here but in mac_lld_start().*/ - for (i = 0; i < SAMA_MAC_RECEIVE_BUFFERS; i++) { - __eth_rd[i].rdes0 = ((uint32_t)__eth_rb[i]) & (SAMA_RDES0_RBAP_MASK); - /* Status reset */ - __eth_rd[i].rdes1 = 0; - /* For last buffer wrap is set */ - if (i == (SAMA_MAC_RECEIVE_BUFFERS - 1)){ - __eth_rd[i].rdes0 |= SAMA_RDES0_WRAP; - } - } - - __eth_td1[0].tdes1 = 0; - __eth_td2[0].tdes1 = 0; - - for (i = 0; i < SAMA_MAC_TRANSMIT_BUFFERS; i++) { - __eth_td[i].tdes0 = (uint32_t)__eth_tb[i]; - /* Status reset */ - __eth_td[i].tdes1 = 0; - /* For last buffer wrap is set */ - if (i == (SAMA_MAC_TRANSMIT_BUFFERS - 1)){ - __eth_td[i].tdes1 |= SAMA_TDES1_WRAP; - __eth_td1[0].tdes1 |= SAMA_TDES1_WRAP; - __eth_td2[0].tdes1 |= SAMA_TDES1_WRAP; - } - } - - /* MAC clocks temporary activation.*/ - pmcEnableETH0(); - - /* Configures MDIO clock */ - GMAC0->GMAC_NCFGR = (GMAC0->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | GMAC_CLK; - - /* Enables management port */ - GMAC0->GMAC_NCR |= GMAC_NCR_MPE; - - /* Selection of the RMII or MII mode based on info exported by board.h.*/ -#if defined(BOARD_PHY_RMII) - GMAC0->GMAC_UR = GMAC_UR_RMII; -#else - GMAC0->GMAC_UR &= ~GMAC_UR_RMII; -#endif - - /* PHY address setup.*/ -#if defined(BOARD_PHY_ADDRESS) - ETHD0.phyaddr = BOARD_PHY_ADDRESS; -#else - mii_find_phy(ÐD0); -#endif - -#if defined(BOARD_PHY_RESET) - /* PHY board-specific reset procedure.*/ - BOARD_PHY_RESET(); -#else - /* PHY soft reset procedure.*/ - mii_write(ÐD0, MII_BMCR, BMCR_RESET); -#if defined(BOARD_PHY_RESET_DELAY) - osalSysPolledDelayX(BOARD_PHY_RESET_DELAY); -#endif - while (mii_read(ÐD0, MII_BMCR) & BMCR_RESET) - ; -#endif - -#if SAMA_MAC_ETH0_CHANGE_PHY_STATE - /* PHY in power down mode until the driver will be started.*/ - mii_write(ÐD0, MII_BMCR, mii_read(ÐD0, MII_BMCR) | BMCR_PDOWN); -#endif - - /* MAC clocks stopped again. */ - pmcDisableETH0(); -} - -/** - * @brief Configures and activates the MAC peripheral. - * - * @param[in] macp pointer to the @p MACDriver object - * - * @notapi - */ -void mac_lld_start(MACDriver *macp) { - unsigned i; - - /* Disable interrupts */ - GMAC0->GMAC_IDR = 0xFFFFFFFF; /* Queue 0 */ - GMAC0->GMAC_IDRPQ[0] = 0xFFFFFFFF; /* Queue 1 */ - GMAC0->GMAC_IDRPQ[1] = 0xFFFFFFFF; /* Queue 2 */ - - /* Clear statistic */ - GMAC0->GMAC_NCR |= GMAC_NCR_CLRSTAT; - - /* Clear rx and tx status bit */ - GMAC0->GMAC_RSR = 0xF; - GMAC0->GMAC_TSR = 0xFF; - - /* Clear interrupt status register */ - GMAC0->GMAC_ISR; /* Queue 0 */ - GMAC0->GMAC_ISRPQ[0]; /* Queue 1 */ - GMAC0->GMAC_ISRPQ[1]; /* Queue 2 */ - - /* Free all descriptors.*/ - for (i = 0; i < SAMA_MAC_RECEIVE_BUFFERS; i++) - __eth_rd[i].rdes0 &= ~SAMA_RDES0_OWN; - - /* Current receive descriptor */ - macp->rxptr = (sama_eth_rx_descriptor_t *)__eth_rd; - - for (i = 0; i < SAMA_MAC_TRANSMIT_BUFFERS; i++) - __eth_td[i].tdes1 |= SAMA_TDES1_LAST_BUFF | SAMA_TDES1_USED; - - __eth_td1[0].tdes1 |= SAMA_TDES1_LAST_BUFF | SAMA_TDES1_USED; - __eth_td2[0].tdes1 |= SAMA_TDES1_LAST_BUFF | SAMA_TDES1_USED; - - macp->txptr = (sama_eth_tx_descriptor_t *)__eth_td; - - /* MAC clocks activation and commanded reset procedure.*/ - pmcEnableETH0(); - - /* Enable interrupt */ - aicSetSourcePriority(ID_GMAC0, SAMA_MAC_ETH0_IRQ_PRIORITY); - aicSetSourceHandler(ID_GMAC0, SAMA_ETH_HANDLER); - aicEnableInt(ID_GMAC0); - -#if SAMA_MAC_ETH0_CHANGE_PHY_STATE - /* PHY in power up mode.*/ - mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) & ~BMCR_PDOWN); -#endif - - /* MAC address setup.*/ - if (macp->config->mac_address == NULL) - mac_lld_set_address(default_mac_address); - else - mac_lld_set_address(macp->config->mac_address); - - /* Transmitter and receiver enabled. - Note that the complete setup of the MAC is performed when the link - status is detected.*/ - uint32_t ncfgr = GMAC0->GMAC_NCFGR; - -#if SAMA_MAC_IP_CHECKSUM_OFFLOAD - GMAC0->GMAC_NCFGR = GMAC_NCFGR_SPD | GMAC_NCFGR_FD | GMAC_NCFGR_RXCOEN | - GMAC_NCFGR_MAXFS | GMAC_NCFGR_RFCS | ncfgr; - GMAC0->GMAC_DCFGR |= GMAC_DCFGR_TXCOEN; -#else - GMAC0->GMAC_NCFGR = GMAC_NCFGR_SPD | GMAC_NCFGR_FD | - GMAC_NCFGR_MAXFS | GMAC_NCFGR_RFCS| ncfgr; -#endif - - /* DMA configuration: - * Descriptor chains pointers. - */ - GMAC0->GMAC_RBQB = (uint32_t)__eth_rd; - /* - * The queue pointers must be initialized and point to - * USED descriptor for all queues including those not - * intended for use. - */ - GMAC0->GMAC_RBQBAPQ[0] = (uint32_t)__eth_rd; - GMAC0->GMAC_RBQBAPQ[1] = (uint32_t)__eth_rd; - - GMAC0->GMAC_TBQB = (uint32_t)__eth_td; - /* - * The queue pointers must be initialized and point to - * USED descriptor for alla queues including those not - * intended for use. - */ - GMAC0->GMAC_TBQBAPQ[0] = (uint32_t)__eth_td1; - GMAC0->GMAC_TBQBAPQ[1] = (uint32_t)__eth_td2; - - /* Enabling required interrupt sources.*/ - GMAC0->GMAC_IER = GMAC_IER_TCOMP | GMAC_IER_RCOMP; - - /* DMA general settings.*/ - uint32_t dcfgr = GMAC0->GMAC_DCFGR & 0xFFFF; - GMAC0->GMAC_DCFGR = dcfgr | GMAC_DCFGR_DRBS(24); - - /* Enable RX and TX.*/ - GMAC0->GMAC_NCR |= GMAC_NCR_RXEN | GMAC_NCR_TXEN; -} - -/** - * @brief Deactivates the MAC peripheral. - * - * @param[in] macp pointer to the @p MACDriver object - * - * @notapi - */ -void mac_lld_stop(MACDriver *macp) { - - if (macp->state != MAC_STOP) { -#if SAMA_MAC_ETH0_CHANGE_PHY_STATE - /* PHY in power down mode until the driver will be restarted.*/ - mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) | BMCR_PDOWN); -#endif - - /* Reset Network Control Register */ - GMAC0->GMAC_NCR &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN); - - /* Disable interrupts */ - GMAC0->GMAC_IDR = 0xFFFFFFFF; - - /* Clear statistic */ - GMAC0->GMAC_NCR |= GMAC_NCR_CLRSTAT; - - /* Clear rx and tx status bit */ - GMAC0->GMAC_RSR = 0xF; - GMAC0->GMAC_TSR = 0xFF; - - /* Clear interrupt status register */ - GMAC0->GMAC_ISR; - - /* MAC clocks stopped.*/ - pmcDisableETH0(); - - /* ISR vector disabled.*/ - aicDisableInt(ID_GMAC0); - } -} - -/** - * @brief Returns a transmission descriptor. - * @details One of the available transmission descriptors is locked and - * returned. - * - * @param[in] macp pointer to the @p MACDriver object - * @param[out] tdp pointer to a @p MACTransmitDescriptor structure - * @return The operation status. - * @retval MSG_OK the descriptor has been obtained. - * @retval MSG_TIMEOUT descriptor not available. - * - * @notapi - */ -msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, - MACTransmitDescriptor *tdp) { - sama_eth_tx_descriptor_t *tdes; - - if (!macp->link_up) - return MSG_TIMEOUT; - - osalSysLock(); - - /* Get Current TX descriptor.*/ - tdes = macp->txptr; - - /* Ensure that descriptor isn't owned by the Ethernet DMA or locked by - another thread.*/ - if ((tdes->tdes1 & SAMA_TDES1_LOCKED) | (!(tdes->tdes1 & SAMA_TDES1_USED))) { - osalSysUnlock(); - return MSG_TIMEOUT; - } - - /* Marks the current descriptor as locked using a reserved bit.*/ - tdes->tdes1 |= SAMA_TDES1_LOCKED; - - if (!(tdes->tdes1 & SAMA_TDES1_WRAP)) { - macp->txptr += 1; - } - else { - macp->txptr = (sama_eth_tx_descriptor_t *)__eth_td; - } - - osalSysUnlock(); - - /* Set the buffer size and configuration.*/ - tdp->offset = 0; - tdp->size = SAMA_MAC_BUFFERS_SIZE; - tdp->physdesc = tdes; - - return MSG_OK; -} - -/** - * @brief Releases a transmit descriptor and starts the transmission of the - * enqueued data as a single frame. - * - * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure - * - * @notapi - */ -void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { - - osalDbgAssert(tdp->physdesc->tdes1 & SAMA_TDES1_USED, - "attempt to release descriptor already owned by DMA"); - - osalSysLock(); - - /* Unlocks the descriptor and returns it to the DMA engine.*/ - tdp->physdesc->tdes1 &= ~(SAMA_TDES1_LOCKED | SAMA_TDES1_USED | SAMA_TDES1_LENGTH_BUFF); - /* Configure lentgh of buffer */ - tdp->physdesc->tdes1 |= (SAMA_TDES1_LENGTH_BUFF & tdp->offset); - - /* Wait for the write to tdes1 to go through before resuming the DMA.*/ - __DSB(); - - if (!(GMAC0->GMAC_TSR & GMAC_TSR_TXGO)) { - GMAC0->GMAC_NCR |= GMAC_NCR_TSTART; - } - - osalSysUnlock(); -} - -/** - * @brief Returns a receive descriptor. - * - * @param[in] macp pointer to the @p MACDriver object - * @param[out] rdp pointer to a @p MACReceiveDescriptor structure - * @return The operation status. - * @retval MSG_OK the descriptor has been obtained. - * @retval MSG_TIMEOUT descriptor not available. - * - * @notapi - */ -msg_t mac_lld_get_receive_descriptor(MACDriver *macp, - MACReceiveDescriptor *rdp) { - sama_eth_rx_descriptor_t *rdes; - - osalSysLock(); - - /* Get Current RX descriptor.*/ - rdes = macp->rxptr; - - /* Iterates through received frames until a valid one is found, invalid - frames are discarded.*/ - while (rdes->rdes0 & SAMA_RDES0_OWN) { - if (rdes->rdes1 & (SAMA_RDES1_EOF | SAMA_RDES1_SOF)) { - /* Found a valid one.*/ - rdp->offset = 0; - /* Only with RFCS set */ - rdp->size = (rdes->rdes1 & SAMA_RDES1_LOF); - rdp->physdesc = rdes; - if (!(rdes->rdes0 & SAMA_RDES0_WRAP)) { - macp->rxptr += 1; - } - else { - macp->rxptr = (sama_eth_rx_descriptor_t *)__eth_rd; - } - osalSysUnlock(); - return MSG_OK; - } - /* Invalid frame found, purging.*/ - rdes->rdes0 &= ~SAMA_RDES0_OWN; - if (!(rdes->rdes0 & SAMA_RDES0_WRAP)) { - rdes += 1; - } - else { - rdes = (sama_eth_rx_descriptor_t *)__eth_rd; - } - } - - /* Next descriptor to check.*/ - macp->rxptr = rdes; - - osalSysUnlock(); - return MSG_TIMEOUT; -} - -/** - * @brief Releases a receive descriptor. - * @details The descriptor and its buffer are made available for more incoming - * frames. - * - * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure - * - * @notapi - */ -void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { - - osalDbgAssert(rdp->physdesc->rdes0 & SAMA_RDES0_OWN, - "attempt to release descriptor not owned by DMA"); - - osalSysLock(); - - /* Give buffer back to the Ethernet DMA.*/ - rdp->physdesc->rdes0 &= ~SAMA_RDES0_OWN; - - /* Wait for the write to rdes0 to go through before resuming the DMA.*/ - __DSB(); - - osalSysUnlock(); -} - -/** - * @brief Updates and returns the link status. - * - * @param[in] macp pointer to the @p MACDriver object - * @return The link status. - * @retval true if the link is active. - * @retval false if the link is down. - * - * @notapi - */ -bool mac_lld_poll_link_status(MACDriver *macp) { - uint32_t maccr, bmsr, bmcr; - - maccr = GMAC0->GMAC_NCFGR; - - /* PHY CR and SR registers read.*/ - (void)mii_read(macp, MII_BMSR); - bmsr = mii_read(macp, MII_BMSR); - bmcr = mii_read(macp, MII_BMCR); - - /* Check on auto-negotiation mode.*/ - if (bmcr & BMCR_ANENABLE) { - uint32_t lpa; - - /* Auto-negotiation must be finished without faults and link established.*/ - if ((bmsr & (BMSR_LSTATUS | BMSR_RFAULT | BMSR_ANEGCOMPLETE)) != - (BMSR_LSTATUS | BMSR_ANEGCOMPLETE)) - return macp->link_up = false; - - /* Auto-negotiation enabled, checks the LPA register.*/ - lpa = mii_read(macp, MII_LPA); - - /* Check on link speed.*/ - if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4)) - maccr |= GMAC_NCFGR_SPD; - else - maccr &= ~GMAC_NCFGR_SPD; - - /* Check on link mode.*/ - if (lpa & (LPA_10FULL | LPA_100FULL)) - maccr |= GMAC_NCFGR_FD; - else - maccr &= ~GMAC_NCFGR_FD; - } - else { - /* Link must be established.*/ - if (!(bmsr & BMSR_LSTATUS)) - return macp->link_up = false; - - /* Check on link speed.*/ - if (bmcr & BMCR_SPEED100) - maccr |= GMAC_NCFGR_SPD; - else - maccr &= ~GMAC_NCFGR_SPD; - - /* Check on link mode.*/ - if (bmcr & BMCR_FULLDPLX) - maccr |= GMAC_NCFGR_FD; - else - maccr &= ~GMAC_NCFGR_FD; - } - - /* Changes the mode in the MAC.*/ - GMAC0->GMAC_NCFGR = maccr; - - /* Returns the link status.*/ - return macp->link_up = true; -} - -/** - * @brief Writes to a transmit descriptor's stream. - * - * @param[in] tdp pointer to a @p MACTransmitDescriptor structure - * @param[in] buf pointer to the buffer containing the data to be - * written - * @param[in] size number of bytes to be written - * @return The number of bytes written into the descriptor's - * stream, this value can be less than the amount - * specified in the parameter @p size if the maximum - * frame size is reached. - * - * @notapi - */ -size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, - uint8_t *buf, - size_t size) { - - osalDbgAssert((tdp->physdesc->tdes1 & SAMA_TDES1_USED), - "attempt to write descriptor not owned"); - - if (size > tdp->size - tdp->offset) - size = tdp->size - tdp->offset; - - if (size > 0) { - memcpy((uint8_t *)(tdp->physdesc->tdes0) + tdp->offset, buf, size); - tdp->offset += size; - } - - return size; -} - -/** - * @brief Reads from a receive descriptor's stream. - * - * @param[in] rdp pointer to a @p MACReceiveDescriptor structure - * @param[in] buf pointer to the buffer that will receive the read data - * @param[in] size number of bytes to be read - * @return The number of bytes read from the descriptor's - * stream, this value can be less than the amount - * specified in the parameter @p size if there are - * no more bytes to read. - * - * @notapi - */ -size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, - uint8_t *buf, - size_t size) { - - osalDbgAssert((rdp->physdesc->rdes0 & SAMA_RDES0_OWN), - "attempt to read descriptor not owned"); - - if (size > rdp->size - rdp->offset) - size = rdp->size - rdp->offset; - - if (size > 0) { - memcpy(buf, (uint8_t *)(rdp->physdesc->rdes0 & SAMA_RDES0_RBAP_MASK) + rdp->offset, size); - rdp->offset += size; - } - return size; -} - -#if MAC_USE_ZERO_COPY || defined(__DOXYGEN__) -/** - * @brief Returns a pointer to the next transmit buffer in the descriptor - * chain. - * @note The API guarantees that enough buffers can be requested to fill - * a whole frame. - * - * @param[in] tdp pointer to a @p MACTransmitDescriptor structure - * @param[in] size size of the requested buffer. Specify the frame size - * on the first call then scale the value down subtracting - * the amount of data already copied into the previous - * buffers. - * @param[out] sizep pointer to variable receiving the buffer size, it is - * zero when the last buffer has already been returned. - * Note that a returned size lower than the amount - * requested means that more buffers must be requested - * in order to fill the frame data entirely. - * @return Pointer to the returned buffer. - * @retval NULL if the buffer chain has been entirely scanned. - * - * @notapi - */ -uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp, - size_t size, - size_t *sizep) { - - if (tdp->offset == 0) { - *sizep = tdp->size; - tdp->offset = size; - return (uint8_t *)tdp->physdesc->tdes0; - } - *sizep = 0; - return NULL; -} - -/** - * @brief Returns a pointer to the next receive buffer in the descriptor - * chain. - * @note The API guarantees that the descriptor chain contains a whole - * frame. - * - * @param[in] rdp pointer to a @p MACReceiveDescriptor structure - * @param[out] sizep pointer to variable receiving the buffer size, it is - * zero when the last buffer has already been returned. - * @return Pointer to the returned buffer. - * @retval NULL if the buffer chain has been entirely scanned. - * - * @notapi - */ -const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp, - size_t *sizep) { - - if (rdp->size > 0) { - *sizep = rdp->size; - rdp->offset = rdp->size; - rdp->size = 0; - return (uint8_t *)rdp->physdesc->rdes0 & SAMA_RDES0_RBAP_MASK; - } - *sizep = 0; - return NULL; -} -#endif /* MAC_USE_ZERO_COPY */ - -#endif /* HAL_USE_MAC */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.h b/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.h deleted file mode 100644 index 7ca57bbf2..000000000 --- a/os/hal/ports/SAMA/LLD/MACv1/hal_mac_lld.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 MACv1/hal_mac_lld.h - * @brief SAMA low level MAC driver header. - * - * @addtogroup MAC - * @{ - */ - -#ifndef HAL_MAC_LLD_H -#define HAL_MAC_LLD_H - -#if HAL_USE_MAC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief This implementation supports the zero-copy mode API. - */ -#define MAC_SUPPORTS_ZERO_COPY FALSE - -/** - * @name RDES0 constants - * @{ - */ -#define SAMA_RDES0_RBAP_MASK 0xFFFFFFFC -#define SAMA_RDES0_WRAP 0x00000002 -#define SAMA_RDES0_OWN 0x00000001 -/** @} */ - -/** - * @name RDES1 constants - * @{ - */ -#define SAMA_RDES1_BROADCAST 0x80000000 -#define SAMA_RDES1_MULTICAST_HASH 0x40000000 -#define SAMA_RDES1_UNICAST_HASH 0x20000000 -#define SAMA_RDES1_ADDR_REG_MATCH 0x08000000 -#define SAMA_RDES1_ADDR_REG 0x06000000 -#define SAMA_RDES1_ID_REG_MATCH 0x01000000 -#define SAMA_RDES1_SNAP_ENCODED 0x01000000 -#define SAMA_RDES1_ID_REG 0x00C00000 -#define SAMA_RDES1_CHECKSUM_IP_TCP 0x00800000 -#define SAMA_RDES1_CHECKSUM_IP_UDP 0x00C00000 -#define SAMA_RDES1_CHECKSUM_IP 0x00400000 -#define SAMA_RDES1_VLAN_TAG_DET 0x00200000 -#define SAMA_RDES1_PRIOR_TAG_DET 0x00100000 -#define SAMA_RDES1_VLAN_PRIOR 0x000E0000 -#define SAMA_RDES1_CFI 0x00010000 -#define SAMA_RDES1_EOF 0x00008000 -#define SAMA_RDES1_SOF 0x00004000 -#define SAMA_RDES1_ADD_BIT_LOF 0x00002000 -#define SAMA_RDES1_BAD_FCS 0x00002000 -#define SAMA_RDES1_LOF 0x00001FFF -/** @} */ - -/** - * @name TDES0 constants - * @{ - */ -#define SAMA_TDES0_BYTE_ADDR 0xFFFFFFFF -/** @} */ - -/** - * @name TDES1 constants - * @{ - */ -#define SAMA_TDES1_USED 0x80000000 -#define SAMA_TDES1_WRAP 0x40000000 -#define SAMA_TDES1_RLE_TX_ERR 0x20000000 -#define SAMA_TDES1_LOCKED 0x10000000 /* NOTE: Pseudo flag. */ -#define SAMA_TDES1_AHB_TX_ERR 0x08000000 -#define SAMA_TDES1_LC_TX_ERR 0x04000000 -#define SAMA_TDES1_CHECKSUM_ERR 0x00700000 -#define SAMA_TDES1_CRC 0x00010000 -#define SAMA_TDES1_LAST_BUFF 0x00008000 -#define SAMA_TDES1_LENGTH_BUFF 0x00003FFF -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Number of available transmit buffers. - */ -#if !defined(SAMA_MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__) -#define SAMA_MAC_TRANSMIT_BUFFERS 2 -#endif - -/** - * @brief Number of available receive buffers. - */ -#if !defined(SAMA_MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__) -#define SAMA_MAC_RECEIVE_BUFFERS 4 -#endif - -/** - * @brief Maximum supported frame size. - */ -#if !defined(SAMA_MAC_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SAMA_MAC_BUFFERS_SIZE 1536 -#endif - -/** - * @brief PHY detection timeout. - * @details Timeout for PHY address detection, the scan for a PHY is performed - * the specified number of times before invoking the failure handler. - * This setting applies only if the PHY address is not explicitly - * set in the board header file using @p BOARD_PHY_ADDRESS. A zero - * value disables the timeout and a single search is performed. - */ -#if !defined(SAMA_MAC_PHY_TIMEOUT) || defined(__DOXYGEN__) -#define SAMA_MAC_PHY_TIMEOUT 100 -#endif - -/** - * @brief Change the PHY power state inside the driver. - */ -#if !defined(SAMA_MAC_ETH0_CHANGE_PHY_STATE) || defined(__DOXYGEN__) -#define SAMA_MAC_ETH0_CHANGE_PHY_STATE TRUE -#endif - -/** - * @brief ETHD0 interrupt priority level setting. - */ -#if !defined(SAMA_MAC_ETH0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_MAC_ETH0_IRQ_PRIORITY 7 -#endif - -/** - * @brief IP checksum offload. - * @details The following modes are available: - * - 0 Function disabled. - * - 1 IP/TCP/UDP header checksum calculation and insertion are enabled. - */ -#if !defined(SAMA_MAC_IP_CHECKSUM_OFFLOAD) || defined(__DOXYGEN__) -#define SAMA_MAC_IP_CHECKSUM_OFFLOAD 1 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an SAMA Ethernet receive descriptor. - */ -typedef struct { - volatile uint32_t rdes0; - volatile uint32_t rdes1; -} sama_eth_rx_descriptor_t; - -/** - * @brief Type of an SAMA Ethernet transmit descriptor. - */ -typedef struct { - volatile uint32_t tdes0; - volatile uint32_t tdes1; -} sama_eth_tx_descriptor_t; - -/** - * @brief Driver configuration structure. - */ -typedef struct { - /** - * @brief MAC address. - */ - uint8_t *mac_address; - /* End of the mandatory fields.*/ -} MACConfig; - -/** - * @brief Structure representing a MAC driver. - */ -struct MACDriver { - /** - * @brief Driver state. - */ - macstate_t state; - /** - * @brief Current configuration data. - */ - const MACConfig *config; - /** - * @brief Transmit semaphore. - */ - threads_queue_t tdqueue; - /** - * @brief Receive semaphore. - */ - threads_queue_t rdqueue; -#if MAC_USE_EVENTS || defined(__DOXYGEN__) - /** - * @brief Receive event. - */ - event_source_t rdevent; -#endif - /* End of the mandatory fields.*/ - /** - * @brief Link status flag. - */ - bool link_up; - /** - * @brief PHY address (pre shifted). - */ - uint32_t phyaddr; - /** - * @brief Receive next frame pointer. - */ - sama_eth_rx_descriptor_t *rxptr; - /** - * @brief Transmit next frame pointer. - */ - sama_eth_tx_descriptor_t *txptr; -}; - -/** - * @brief Structure representing a transmit descriptor. - */ -typedef struct { - /** - * @brief Current write offset. - */ - size_t offset; - /** - * @brief Available space size. - */ - size_t size; - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the physical descriptor. - */ - sama_eth_tx_descriptor_t *physdesc; -} MACTransmitDescriptor; - -/** - * @brief Structure representing a receive descriptor. - */ -typedef struct { - /** - * @brief Current read offset. - */ - size_t offset; - /** - * @brief Available data size. - */ - size_t size; - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the physical descriptor. - */ - sama_eth_rx_descriptor_t *physdesc; -} MACReceiveDescriptor; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern MACDriver ETHD0; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void mii_write(MACDriver *macp, uint32_t reg, uint32_t value); - uint32_t mii_read(MACDriver *macp, uint32_t reg); - void mac_lld_init(void); - void mac_lld_start(MACDriver *macp); - void mac_lld_stop(MACDriver *macp); - msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, - MACTransmitDescriptor *tdp); - void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp); - msg_t mac_lld_get_receive_descriptor(MACDriver *macp, - MACReceiveDescriptor *rdp); - void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp); - bool mac_lld_poll_link_status(MACDriver *macp); - size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, - uint8_t *buf, - size_t size); - size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, - uint8_t *buf, - size_t size); -#if MAC_USE_ZERO_COPY - uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp, - size_t size, - size_t *sizep); - const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp, - size_t *sizep); -#endif /* MAC_USE_ZERO_COPY */ -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_MAC */ - -#endif /* HAL_MAC_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/PIOv1/driver.mk b/os/hal/ports/SAMA/LLD/PIOv1/driver.mk deleted file mode 100644 index bba9eb628..000000000 --- a/os/hal/ports/SAMA/LLD/PIOv1/driver.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c -endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/PIOv1 diff --git a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c b/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c deleted file mode 100644 index dbf5c36a4..000000000 --- a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 PIOv1/hal_pal_lld.c - * @brief SAMA PAL low level driver code. - * - * @addtogroup PAL - * @{ - */ - -#include "hal.h" - -#if HAL_USE_PAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -#define __PIOA ((Pio *)0xFC038000U) - -#define EVENTS_NUMBER (4 * 32) - -/** - * @brief PIOA interrupt priority level setting. - */ -#define SAMA_PIOA_IRQ_PRIORITY 2 - -/** - * @brief PIOB interrupt priority level setting. - */ -#define SAMA_PIOB_IRQ_PRIORITY 2 - -/** - * @brief PIOC interrupt priority level setting. - */ -#define SAMA_PIOC_IRQ_PRIORITY 2 - -/** - * @brief PIOD interrupt priority level setting. - */ -#define SAMA_PIOD_IRQ_PRIORITY 2 -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -/** - * @brief Event records for the GPIO interrupts. - */ -palevent_t _pal_events[EVENTS_NUMBER]; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ -/** - * @brief PIOA interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_PIOA_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr, imr, is; - uint8_t i, j; - - sr = pal_lld_read_status(PIOA); - imr = pal_lld_read_int_mask(PIOA); - - is = sr & imr; - for (j = 0, i = 0; i < 32; i++, j++) { - if (!(is & (0x1 << j))) { - continue; - } -#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__) - if (_pal_events[i].cb != NULL) { - _pal_events[i].cb(&is); - } -#endif - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief PIOB interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_PIOB_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr, imr, is; - uint8_t i, j; - - sr = pal_lld_read_status(PIOB); - imr = pal_lld_read_int_mask(PIOB); - - is = sr & imr; - for (j = 0, i = 32; i < 64; i++, j++) { - if (!(is & (0x1 << j))) { - continue; - } -#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__) - if (_pal_events[i].cb != NULL) { - _pal_events[i].cb(&is); - } -#endif - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief PIOC interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_PIOC_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr, imr, is; - uint8_t i, j; - - sr = pal_lld_read_status(PIOC); - imr = pal_lld_read_int_mask(PIOC); - - is = sr & imr; - for (j = 0, i = 64; i < 96; i++, j++) { - if (!(is & (0x1 << j))) { - continue; - } -#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__) - if (_pal_events[i].cb != NULL) { - _pal_events[i].cb(&is); - } -#endif - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief PIOD interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_PIOD_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr, imr, is; - uint8_t i, j; - - sr = pal_lld_read_status(PIOD); - imr = pal_lld_read_int_mask(PIOD); - - is = sr & imr; - for (j = 0, i = 96; i < 128; i++, j++) { - if (!(is & (0x1 << j))) { - continue; - } -#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__) - if (_pal_events[i].cb != NULL) { - _pal_events[i].cb(&is); - } -#endif - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ -/** - * @brief PAL driver initialization. - * - * @notapi - */ -void _pal_lld_init(void) { - -#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) - unsigned i; - - for (i = 0; i < EVENTS_NUMBER; i++) { - _pal_init_event(i); - } - - /* - * Clears status register - */ - pal_lld_read_status(PIOA); - pal_lld_read_status(PIOB); - pal_lld_read_status(PIOC); - pal_lld_read_status(PIOD); - - aicSetSourcePriority(ID_PIOA, SAMA_PIOA_IRQ_PRIORITY); - aicSetSourceHandler(ID_PIOA, SAMA_PIOA_HANDLER); - aicEnableInt(ID_PIOA); - - aicSetSourcePriority(ID_PIOB, SAMA_PIOB_IRQ_PRIORITY); - aicSetSourceHandler(ID_PIOB, SAMA_PIOB_HANDLER); - aicEnableInt(ID_PIOB); - - aicSetSourcePriority(ID_PIOC, SAMA_PIOC_IRQ_PRIORITY); - aicSetSourceHandler(ID_PIOC, SAMA_PIOC_HANDLER); - aicEnableInt(ID_PIOC); - - aicSetSourcePriority(ID_PIOD, SAMA_PIOD_IRQ_PRIORITY); - aicSetSourceHandler(ID_PIOD, SAMA_PIOD_HANDLER); - aicEnableInt(ID_PIOD); -#endif /* #if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) */ -} - -/** - * @brief Pads mode setup. - * @details This function programs a pads group belonging to the same port - * with the specified mode. - * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum - * speed. - * - * @param[in] port the port identifier - * @param[in] mask the group mask - * @param[in] mode the mode - * - * @notapi - */ -void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - iomode_t mode) { - - uint32_t mskr = (mask); - uint32_t cfgr = (mode & (PAL_SAMA_CFGR_MASK)); - -#if SAMA_HAL_IS_SECURE - if(mode && PAL_SAMA_SECURE_MASK) { - port->SIOSR = mask; - } - else { - port->SIONR = mask; - } -#endif /* SAMA_HAL_IS_SECURE */ - port->MSKR = mskr; - port->CFGR = cfgr; -} - -#if SAMA_HAL_IS_SECURE -/** - * @brief Configures debouncing time for pads. - * - * @param[in] db_time debouncing time - * - * @api - */ -void pal_lld_cfg_debouncing_time(uint32_t db_time) { - - /* - * Debouncing time configuration only in SECURE STATE - */ - __PIOA->S_PIO_SCDR = db_time & 0x3FFF; -} -#endif - -/** - * @brief Reads/Clears Interrupt Status Register. - * - * @param[in] port port identifier - * - * @api - */ -uint32_t pal_lld_read_status(ioportid_t port) { - return port->ISR; -} - -/** - * @brief Reads Interrupt Mask Register. - * - * @param[in] port port identifier - * - * @api - */ -uint32_t pal_lld_read_int_mask(ioportid_t port) { - return port->IMR; -} - -/** - * @brief Reads Configuration Register. - * - * @param[in] port port identifier - * - * @api - */ -uint32_t pal_lld_read_cfgr(ioportid_t port) { - return port->CFGR; -} - -#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) -/** - * @brief Pad event enable. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] mode pad event mode - * - * @notapi - */ -void _pal_lld_enablepadevent(ioportid_t port, - iopadid_t pad, - ioeventmode_t mode) { - - port->MSKR = pad; - port->CFGR |= mode; - port->IER = pad; -} - -/** - * @brief Returns a PAL event structure associated to a pad. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @notapi - */ -palevent_t* pal_lld_get_pad_event(ioportid_t port, iopadid_t pad) { - - palevent_t* palevt = NULL; - - if (port == PIOA) { - palevt = &_pal_events[pad]; - } - else if (port == PIOB) { - palevt = &_pal_events[32 + pad]; - } - else if (port == PIOC) { - palevt = &_pal_events[64 + pad]; - } - else { - palevt = &_pal_events[96 + pad]; - } - - return palevt; -} - -/** - * @brief Pad event disable. - * @details This function disables previously programmed event callbacks. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @notapi - */ -void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) { - - port->IDR |= pad; - -#if PAL_USE_CALLBACKS || PAL_USE_WAIT - /* Callback cleared and/or thread reset.*/ - _pal_clear_event(pad); -#endif -} -#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */ - -#endif /* HAL_USE_PAL */ -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h b/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h deleted file mode 100644 index 53386ba5b..000000000 --- a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h +++ /dev/null @@ -1,559 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 PIOv1/hal_pal_lld.h - * @brief SAMA PAL low level driver header. - * - * @addtogroup PAL - * @{ - */ - -#ifndef HAL_PAL_LLD_H -#define HAL_PAL_LLD_H - -#if HAL_USE_PAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Unsupported modes and specific modes */ -/*===========================================================================*/ -/* Specifies palInit() without parameter, required until all platforms will - be updated to the new style.*/ -#define PAL_NEW_INIT - -#undef PAL_MODE_RESET -#undef PAL_MODE_UNCONNECTED -#undef PAL_MODE_INPUT -#undef PAL_MODE_INPUT_PULLUP -#undef PAL_MODE_INPUT_PULLDOWN -#undef PAL_MODE_INPUT_ANALOG -#undef PAL_MODE_OUTPUT_PUSHPULL -#undef PAL_MODE_OUTPUT_OPENDRAIN - -/** - * @name SAMA-specific I/O mode flags - * @{ - */ -#define PAL_SAMA_FUNC_MASK (7U << 0U) -#define PAL_SAMA_FUNC_GPIO (0U << 0U) -#define PAL_SAMA_FUNC_PERIPH_A (1U << 0U) -#define PAL_SAMA_FUNC_PERIPH_B (2U << 0U) -#define PAL_SAMA_FUNC_PERIPH_C (3U << 0U) -#define PAL_SAMA_FUNC_PERIPH_D (4U << 0U) -#define PAL_SAMA_FUNC_PERIPH_E (5U << 0U) -#define PAL_SAMA_FUNC_PERIPH_F (6U << 0U) -#define PAL_SAMA_FUNC_PERIPH_G (7U << 0U) - -#define PAL_SAMA_DIR_MASK (1U << 8U) -#define PAL_SAMA_DIR_INPUT (0U << 8U) -#define PAL_SAMA_DIR_OUTPUT (1U << 8U) - -#define PAL_SAMA_PUEN_MASK (1U << 9U) -#define PAL_SAMA_PUEN_PULLUP (1U << 9U) - -#define PAL_SAMA_PDEN_MASK (1U << 10U) -#define PAL_SAMA_PDEN_PULLDOWN (1U << 10U) - -#define PAL_SAMA_IFEN_MASK (1U << 12U) -#define PAL_SAMA_PDEN_INPUTFILTER (1U << 12U) - -#define PAL_SAMA_IFSCEN_MASK (1U << 13U) -#define PAL_SAMA_IFSCEN_MCK_2 (0U << 13U) -#define PAL_SAMA_IFSCEN_SLCK_2 (1U << 13U) - -#define PAL_SAMA_OPD_MASK (1U << 14U) -#define PAL_SAMA_OPD_PUSHPULL (0U << 14U) -#define PAL_SAMA_OPD_OPENDRAIN (1U << 14U) - -#define PAL_SAMA_SCHMITT_MASK (1U << 15U) -#define PAL_SAMA_SCHMITT (1U << 15U) - -#define PAL_SAMA_DRVSTR_MASK (3U << 16U) -#define PAL_SAMA_DRVSTR_LO (1U << 16U) -#define PAL_SAMA_DRVSTR_ME (2U << 16U) -#define PAL_SAMA_DRVSTR_HI (3U << 16U) - -#define PAL_SAMA_EVTSEL_MASK (7U << 24U) -#define PAL_SAMA_EVTSEL_FALLING (0U << 24U) -#define PAL_SAMA_EVTSEL_RISING (1U << 24U) -#define PAL_SAMA_EVTSEL_BOTH (2U << 24U) -#define PAL_SAMA_EVTSEL_LOW (3U << 24U) -#define PAL_SAMA_EVTSEL_HIGH (4U << 24U) - -#define PAL_SAMA_PCFS_MASK (1U << 29U) -#define PAL_SAMA_ICFS_MASK (1U << 30U) - - -#define PAL_SAMA_CFGR_MASK PAL_SAMA_FUNC_MASK | \ - PAL_SAMA_DIR_MASK | \ - PAL_SAMA_PUEN_MASK | \ - PAL_SAMA_PDEN_MASK | \ - PAL_SAMA_IFEN_MASK | \ - PAL_SAMA_IFSCEN_MASK | \ - PAL_SAMA_OPD_MASK | \ - PAL_SAMA_SCHMITT_MASK | \ - PAL_SAMA_DRVSTR_MASK | \ - PAL_SAMA_EVTSEL_MASK - -#if SAMA_HAL_IS_SECURE -#define PAL_SAMA_SECURE_MASK (1U << 31U) - -#define PAL_SAMA_NON_SECURE (0U << 31U) -#define PAL_SAMA_SECURE (1U << 31U) -#endif /* SAMA_HAL_IS_SECURE */ - -/** - * @name Standard I/O mode flags - * @{ - */ -/** - * @brief Implemented as input. - */ -#define PAL_MODE_RESET (PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_SCHMITT) - -/** - * @brief Implemented as input with pull-up. - */ -#define PAL_MODE_UNCONNECTED (PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_SCHMITT | \ - PAL_SAMA_PUEN_PULLUP) - -/** - * @brief Regular input high-Z pad. - */ -#define PAL_MODE_INPUT (PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_SCHMITT) - -/** - * @brief Input pad with weak pull up resistor. - */ -#define PAL_MODE_INPUT_PULLUP (PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_SCHMITT | \ - PAL_SAMA_PUEN_PULLUP) - -/** - * @brief Input pad with weak pull down resistor. - */ -#define PAL_MODE_INPUT_PULLDOWN (PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_SCHMITT | \ - PAL_SAMA_PDEN_PULLDOWN) - -/** - * @brief Analog input mode. - */ -#define PAL_MODE_INPUT_ANALOG PAL_SAMA_DIR_INPUT - -/** - * @brief Push-pull output pad. - */ -#define PAL_MODE_OUTPUT_PUSHPULL PAL_SAMA_DIR_OUTPUT - -/** - * @brief Open-drain output pad. - */ -#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_SAMA_DIR_OUTPUT | \ - PAL_SAMA_OPD_OPENDRAIN) - -#if SAMA_HAL_IS_SECURE || defined(__DOXYGEN__) -/** - * @brief Secure pad. - * @note Available only on Secure HAL. - */ -#define PAL_MODE_SECURE PAL_SAMA_SECURE - -/** - * @brief Non secure pad. - * @note Available only on Secure HAL. - */ -#define PAL_MODE_NON_SECURE PAL_SAMA_NON_SECURE -#endif -/** @} */ - -/* Discarded definitions from the Atmel headers, the PAL driver uses its own - definitions in order to have an unified handling for all devices. - Unfortunately the ST headers have no uniform definitions for the same - objects across the various sub-families.*/ -#undef PIOA - -/** - * @name PIO ports definitions - * @{ - */ -#define PIOA ((sama_pio_t *)PIOA_BASE) -#define PIOB ((sama_pio_t *)PIOB_BASE) -#define PIOC ((sama_pio_t *)PIOC_BASE) -#define PIOD ((sama_pio_t *)PIOD_BASE) -/** @} */ - -/*===========================================================================*/ -/* I/O Ports Types and constants. */ -/*===========================================================================*/ - -/** - * @name Port related definitions - * @{ - */ -/** - * @brief Width, in bits, of an I/O port. - */ -#define PAL_IOPORTS_WIDTH 32 - -/** - * @brief Whole port mask. - * @details This macro specifies all the valid bits into a port. - */ -#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF) -/** @} */ - -/** - * @name Line handling macros - * @{ - */ -/** - * @brief Forms a line identifier. - * @details A port/pad pair are encoded into an @p ioline_t type. The encoding - * of this type is platform-dependent. - * @note In this driver the pad number is encoded in the lower 5 bits of - * the PIO address which are guaranteed to be zero. - */ -#define PAL_LINE(port, pad) \ - ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad))) - -/** - * @brief Decodes a port identifier from a line identifier. - */ -#define PAL_PORT(line) \ - ((sama_pio_t *)(((uint32_t)(line)) & 0xFFFFFFE0U)) - -/** - * @brief Decodes a pad identifier from a line identifier. - */ -#define PAL_PAD(line) \ - ((uint32_t)((uint32_t)(line) & 0x0000001FU)) - -/** - * @brief Value identifying an invalid line. - */ -#define PAL_NOLINE 0U -/** @} */ - -/** - * @brief SAMA PIO registers block. - */ -#if SAMA_HAL_IS_SECURE -typedef struct { - volatile uint32_t MSKR; - volatile uint32_t CFGR; - volatile uint32_t PDSR; - volatile uint32_t LOCKSR; - volatile uint32_t SODR; - volatile uint32_t CODR; - volatile uint32_t ODSR; - volatile uint32_t Reserved1; - volatile uint32_t IER; - volatile uint32_t IDR; - volatile uint32_t IMR; - volatile uint32_t ISR; - volatile uint32_t SIONR; - volatile uint32_t SIOSR; - volatile uint32_t IOSSR; - volatile uint32_t IOFR; -} sama_pio_t; -#else -typedef struct { - volatile uint32_t MSKR; - volatile uint32_t CFGR; - volatile uint32_t PDSR; - volatile uint32_t LOCKSR; - volatile uint32_t SODR; - volatile uint32_t CODR; - volatile uint32_t ODSR; - volatile uint32_t Reserved1; - volatile uint32_t IER; - volatile uint32_t IDR; - volatile uint32_t IMR; - volatile uint32_t ISR; - volatile uint32_t Reserved2[3]; - volatile uint32_t IOFR; -} sama_pio_t; -#endif - -/** - * @brief SAMA PIO static initializer. - * @details It is a dummy. - */ -typedef uint32_t PALConfig; - -/** - * @brief Type of digital I/O port sized unsigned integer. - */ -typedef uint32_t ioportmask_t; - -/** - * @brief Type of digital I/O modes. - */ -typedef uint32_t iomode_t; - -/** - * @brief Type of an I/O line. - */ -typedef uint32_t ioline_t; - -/** - * @brief Type of an event mode. - */ -typedef uint32_t ioeventmode_t; - -/** - * @brief Type of a port Identifier. - * @details This type can be a scalar or some kind of pointer, do not make - * any assumption about it, use the provided macros when populating - * variables of this type. - */ -typedef sama_pio_t * ioportid_t; - -/** - * @brief Type of an pad identifier. - */ -typedef uint32_t iopadid_t; - -/*===========================================================================*/ -/* I/O Ports Identifiers. */ -/* The low level driver wraps the definitions already present in the SAMA */ -/* firmware library. */ -/*===========================================================================*/ - -/** - * @brief PIO port A identifier. - */ -#if SAMA_HAS_PIOA || defined(__DOXYGEN__) -#define IOPORT1 PIOA -#endif - -/** - * @brief PIO port B identifier. - */ -#if SAMA_HAS_PIOB || defined(__DOXYGEN__) -#define IOPORT2 PIOB -#endif - -/** - * @brief PIO port C identifier. - */ -#if SAMA_HAS_PIOC || defined(__DOXYGEN__) -#define IOPORT3 PIOC -#endif - -/** - * @brief PIO port D identifier. - */ -#if SAMA_HAS_PIOD || defined(__DOXYGEN__) -#define IOPORT4 PIOD -#endif - -/*===========================================================================*/ -/* Implementation, some of the following macros could be implemented as */ -/* functions, if so please put them in pal_lld.c. */ -/*===========================================================================*/ -/** - * @brief GPIO ports subsystem initialization. - * - * @notapi - */ -#define pal_lld_init() _pal_lld_init() - -/** - * @brief Reads an I/O port. - * @details This function is implemented by reading the PIO PDSR register, the - * implementation has no side effects. - * @note This function is not meant to be invoked directly by the application - * code. - * - * @param[in] port port identifier - * @return The port bits. - * - * @notapi - */ -#define pal_lld_readport(port) ((port)->PDSR) - -/** - * @brief Reads the output latch. - * @details This function is implemented by reading the PIO ODSR register, the - * implementation has no side effects. - * @note This function is not meant to be invoked directly by the application - * code. - * - * @param[in] port port identifier - * @return The latched logical states. - * - * @notapi - */ -#define pal_lld_readlatch(port) ((port)->ODSR) - -/** - * @brief Writes on a I/O port. - * @details This function is implemented by writing the PIO ODR register, the - * implementation has no side effects. - * - * @param[in] port port identifier - * @param[in] bits bits to be written on the specified port - * - * @notapi - */ -#define pal_lld_writeport(port, bits) \ - do { \ - (port)->MSKR = 0xFFFFFFFFU; \ - (port)->ODSR = (bits); \ - } while (false) - -/** - * @brief Sets a bits mask on a I/O port. - * @details This function is implemented by writing the PIO BSRR register, the - * implementation has no side effects. - * - * @param[in] port port identifier - * @param[in] bits bits to be ORed on the specified port - * - * @notapi - */ -#define pal_lld_setport(port, bits) ((port)->SODR = (bits)) - -/** - * @brief Clears a bits mask on a I/O port. - * @details This function is implemented by writing the PIO BSRR register, the - * implementation has no side effects. - * - * @param[in] port port identifier - * @param[in] bits bits to be cleared on the specified port - * - * @notapi - */ -#define pal_lld_clearport(port, bits) ((port)->CODR = (bits)) - -/** - * @brief Writes a group of bits. - * @details This function is implemented by writing the PIO BSRR register, the - * implementation has no side effects. - * - * @param[in] port port identifier - * @param[in] mask group mask - * @param[in] offset the group bit offset within the port - * @param[in] bits bits to be written. Values exceeding the group - * width are masked. - * - * @notapi - */ -#define pal_lld_writegroup(port, mask, offset, bits) \ - do { \ - (port)->MSKR = ((mask) << (offset)); \ - (port)->ODSR = (((bits) & (mask)) << (offset)); \ - } while (false) - -/** - * @brief Pads group mode setup. - * @details This function programs a pads group belonging to the same port - * with the specified mode. - * - * @param[in] port port identifier - * @param[in] mask group mask - * @param[in] offset group bit offset within the port - * @param[in] mode group mode - * - * @notapi - */ -#define pal_lld_setgroupmode(port, mask, offset, mode) \ - _pal_lld_setgroupmode(port, mask << offset, mode) - -/** - * @brief Writes a logical state on an output pad. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] bit logical value, the value must be @p PAL_LOW or - * @p PAL_HIGH - * - * @notapi - */ -#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit) - -/** - * @brief Pad event enable. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] mode pad event mode - * - * @notapi - */ -#define pal_lld_enablepadevent(port, pad, mode) \ - _pal_lld_enablepadevent(port, pad, mode) - -/** - * @brief Pad event disable. - * @details This function disables previously programmed event callbacks. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @notapi - */ -#define pal_lld_disablepadevent(port, pad) \ - _pal_lld_disablepadevent(port, pad) - -/** - * @brief Returns a PAL event structure associated to a line. - * - * @param[in] line line identifier - * - * @notapi - */ -#define pal_lld_get_line_event(line) \ - &_pal_events[PAL_PAD(line)] - -#if !defined(__DOXYGEN__) -extern palevent_t _pal_events[4 * 32]; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void _pal_lld_init(void); - void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - iomode_t mode); - void _pal_lld_enablepadevent(ioportid_t port, - iopadid_t pad, - ioeventmode_t mode); - void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad); - palevent_t* pal_lld_get_pad_event(ioportid_t port, iopadid_t pad); - /* LLD only functions */ -#if SAMA_HAL_IS_SECURE - void pal_lld_cfg_debouncing_time(uint32_t db_time); -#endif - uint32_t pal_lld_read_status(ioportid_t port); - uint32_t pal_lld_read_int_mask(ioportid_t port); - uint32_t pal_lld_read_cfgr(ioportid_t port); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_PAL */ - -#endif /* HAL_PAL_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/RNGv1/driver.mk b/os/hal/ports/SAMA/LLD/RNGv1/driver.mk deleted file mode 100644 index 163c48a70..000000000 --- a/os/hal/ports/SAMA/LLD/RNGv1/driver.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_TRNG TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c -endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/RNGv1 diff --git a/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c b/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c deleted file mode 100644 index 6d8fde7d6..000000000 --- a/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_trng_lld.c - * @brief STM32 TRNG subsystem low level driver source. - * - * @addtogroup TRNG - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_TRNG == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief TRNGD0 driver identifier. - */ -#if (SAMA_TRNG_USE_TRNG0 == TRUE) || defined(__DOXYGEN__) -TRNGDriver TRNGD0; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -static const TRNGConfig default_cfg = {0}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level TRNG driver initialization. - * - * @notapi - */ -void trng_lld_init(void) { - -#if SAMA_TRNG_USE_TRNG0 == TRUE - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TRNG, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - /* Driver initialization.*/ - trngObjectInit(&TRNGD0); - TRNGD0.trng = TRNG; -#endif -} - -/** - * @brief Configures and activates the TRNG peripheral. - * - * @param[in] trngp pointer to the @p TRNGDriver object - * - * @notapi - */ -void trng_lld_start(TRNGDriver *trngp) { - - /* There is no real configuration but setting up a valid pointer anyway.*/ - if (trngp->config == NULL) { - trngp->config = &default_cfg; - } - - if (trngp->state == TRNG_STOP) { - /* Enables the peripheral.*/ -#if SAMA_TRNG_USE_TRNG0 == TRUE - if (&TRNGD0 == trngp) { - pmcEnableTRNG0(); - } -#endif - } - /* Configures the peripheral.*/ - trngp->trng->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY_PASSWD; -} - -/** - * @brief Deactivates the TRNG peripheral. - * - * @param[in] trngp pointer to the @p TRNGDriver object - * - * @notapi - */ -void trng_lld_stop(TRNGDriver *trngp) { - - if (trngp->state == TRNG_READY) { - /* Resets the peripheral.*/ - trngp->trng->TRNG_CR = TRNG_CR_KEY_PASSWD; - - /* Disables the peripheral.*/ -#if SAMA_TRNG_USE_TRNG0 == TRUE - if (&TRNGD0 == trngp) { - pmcDisableTRNG0(); - } -#endif - } -} - -/** - * @brief True random numbers generator. - * @note The function is blocking and likely performs polled waiting - * inside the low level implementation. - * - * @param[in] trngp pointer to the @p TRNGDriver object - * @param[in] size size of output buffer - * @param[out] out output buffer - * @return The operation status. - * @retval false if a random number has been generated. - * @retval true if an HW error occurred. - * - * @api - */ -bool trng_lld_generate(TRNGDriver *trngp, size_t size, uint8_t *out) { - - while (true) { - uint32_t r, tmo; - size_t i; - - /* Waiting for a random number in data register.*/ - tmo = SAMA_DATA_FETCH_ATTEMPTS; - while ((tmo > 0) && ((trngp->trng->TRNG_ISR & TRNG_ISR_DATRDY) == 0)) { - tmo--; - if (tmo == 0) { - return true; - } - } - - /* Getting the generated random number.*/ - r = trngp->trng->TRNG_ODATA; - - /* Writing in the output buffer.*/ - for (i = 0; i < sizeof (uint32_t) / sizeof (uint8_t); i++) { - *out++ = (uint8_t)r; - r = r >> 8; - size--; - if (size == 0) { - return false; - } - } - } -} - -#endif /* HAL_USE_TRNG == TRUE */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.h b/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.h deleted file mode 100644 index 146635db4..000000000 --- a/os/hal/ports/SAMA/LLD/RNGv1/hal_trng_lld.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_trng_lld.h - * @brief SAMA TRNG subsystem low level driver header. - * - * @addtogroup TRNG - * @{ - */ - -#ifndef HAL_TRNG_LLD_H -#define HAL_TRNG_LLD_H - -#if (HAL_USE_TRNG == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name SAMA configuration options - * @{ - */ -/** - * @brief TRNGD0 driver enable switch. - * @details If set to @p TRUE the support for TRNGD0 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_TRNG_USE_TRNG0) || defined(__DOXYGEN__) -#define SAMA_TRNG_USE_TRNG0 FALSE -#endif - -/** - * @brief TRNGD0 data available timeout counter. - * @details Number of status register fetches before failing. - */ -#if !defined(SAMA_DATA_FETCH_ATTEMPTS) || defined(__DOXYGEN__) -#define SAMA_DATA_FETCH_ATTEMPTS 1000 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if !SAMA_TRNG_USE_TRNG0 -#error "TRNG driver activated but no RNG peripheral assigned" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Low level fields of the TRNG configuration structure. - */ -#define trng_lld_config_fields \ - /* Dummy configuration, it is not needed.*/ \ - uint32_t dummy - -/** - * @brief Low level fields of the TRNG driver structure. - */ -#define trng_lld_driver_fields \ - /* Pointer to the RNG registers block.*/ \ - Trng *trng; - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if (SAMA_TRNG_USE_TRNG0 == TRUE) && !defined(__DOXYGEN__) -extern TRNGDriver TRNGD0; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void trng_lld_init(void); - void trng_lld_start(TRNGDriver *trngp); - void trng_lld_stop(TRNGDriver *trngp); - bool trng_lld_generate(TRNGDriver *trngp, size_t size, uint8_t *out); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_TRNG == TRUE */ - -#endif /* HAL_TRNG_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/RTCv1/driver.mk b/os/hal/ports/SAMA/LLD/RTCv1/driver.mk deleted file mode 100644 index 6a4057e4a..000000000 --- a/os/hal/ports/SAMA/LLD/RTCv1/driver.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c -endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/RTCv1 diff --git a/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c b/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c deleted file mode 100644 index 691a3cc15..000000000 --- a/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv1/hal_rtc_lld.c - * @brief SAMA RTC low level driver. - * - * @addtogroup RTC - * @{ - */ - -#include "hal.h" - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -#define RTC_TIMR_PM_OFFSET 22 -#define RTC_TIMR_HT_OFFSET 20 -#define RTC_TIMR_HU_OFFSET 16 -#define RTC_TIMR_MNT_OFFSET 12 -#define RTC_TIMR_MNU_OFFSET 8 -#define RTC_TIMR_ST_OFFSET 4 -#define RTC_TIMR_SU_OFFSET 0 - -#define RTC_CALR_DT_OFFSET 28 -#define RTC_CALR_DU_OFFSET 24 -#define RTC_CALR_WDU_OFFSET 21 -#define RTC_CALR_MT_OFFSET 20 -#define RTC_CALR_MU_OFFSET 16 -#define RTC_CALR_YT_OFFSET 12 -#define RTC_CALR_YU_OFFSET 8 -#define RTC_CALR_CT_OFFSET 4 -#define RTC_CALR_CU_OFFSET 0 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief RTC driver identifier. - */ -RTCDriver RTCD0; - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief RTC interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_RTC_HANDLER) { - uint16_t sr, imr; - - OSAL_IRQ_PROLOGUE(); - - sr = RTCD0.rtc->RTC_SR; - imr = RTCD0.rtc->RTC_IMR; - - if ((sr & RTC_SR_SEC) && (imr & RTC_IMR_SEC)) { - RTCD0.rtc->RTC_SCCR = RTC_SCCR_SECCLR; - RTCD0.callback(&RTCD0, RTC_EVENT_SECOND); - } - if ((sr & RTC_SR_ALARM) && (imr & RTC_IMR_ALR)) { - RTCD0.rtc->RTC_SCCR = RTC_SCCR_ALRCLR; - RTCD0.callback(&RTCD0, RTC_EVENT_ALARM); - } - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Beginning of configuration procedure. - * - * @notapi - */ -static void rtc_enter_init(void) { - - /* Stop RTC_TIMR and RTC_CALR */ - RTCD0.rtc->RTC_CR |= RTC_CR_UPDCAL; - RTCD0.rtc->RTC_CR |= RTC_CR_UPDTIM; -} - -/** - * @brief Finalizing of configuration procedure. - * - * @notapi - */ -static void rtc_exit_init(void) { - - RTCD0.rtc->RTC_CR &= ~RTC_CR_UPDTIM; - RTCD0.rtc->RTC_CR &= ~RTC_CR_UPDCAL; -} - -/** - * @brief Converts time from RTC_TIMR register encoding to timespec. - * - * @param[in] timr TIMR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_time(uint32_t timr, RTCDateTime *timespec) { - uint32_t n; - - n = ((timr >> RTC_TIMR_HT_OFFSET) & 3) * 36000000; - n += ((timr >> RTC_TIMR_HU_OFFSET) & 15) * 3600000; - n += ((timr >> RTC_TIMR_MNT_OFFSET) & 7) * 600000; - n += ((timr >> RTC_TIMR_MNU_OFFSET) & 15) * 60000; - n += ((timr >> RTC_TIMR_ST_OFFSET) & 7) * 10000; - n += ((timr >> RTC_TIMR_SU_OFFSET) & 15) * 1000; - timespec->millisecond = n; -} - -/** - * @brief Converts date from RTC_CALR register encoding to timespec. - * - * @param[in] calr RTC_CALR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_date(uint32_t calr, RTCDateTime *timespec) { - - uint32_t centuryYear = (((calr >> RTC_CALR_CT_OFFSET) & 7) * 1000) + - (((calr >> RTC_CALR_CU_OFFSET) & 15) * 100) + - (((calr >> RTC_CALR_YT_OFFSET) & 15) * 10) + - ((calr >> RTC_CALR_YU_OFFSET) & 15); - timespec->year = (centuryYear - 1980); - timespec->month = (((calr >> RTC_CALR_MT_OFFSET) & 1) * 10) + - ((calr >> RTC_CALR_MU_OFFSET) & 15); - timespec->day = (((calr >> RTC_CALR_DT_OFFSET) & 3) * 10) + - ((calr >> RTC_CALR_DU_OFFSET) & 15); - timespec->dayofweek = (calr >> RTC_CALR_WDU_OFFSET) & 7; -} - -/** - * @brief Converts time from timespec to RTC_TIMR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the TIMR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_time(const RTCDateTime *timespec) { - uint32_t n, timr = 0; - - /* Subseconds cannot be set.*/ - n = timespec->millisecond / 1000; - - /* Seconds conversion.*/ - timr = timr | ((n % 10) << RTC_TIMR_SU_OFFSET); - n /= 10; - timr = timr | ((n % 6) << RTC_TIMR_ST_OFFSET); - n /= 6; - - /* Minutes conversion.*/ - timr = timr | ((n % 10) << RTC_TIMR_MNU_OFFSET); - n /= 10; - timr = timr | ((n % 6) << RTC_TIMR_MNT_OFFSET); - n /= 6; - - /* Hours conversion.*/ - timr = timr | ((n % 10) << RTC_TIMR_HU_OFFSET); - n /= 10; - timr = timr | (n << RTC_TIMR_HT_OFFSET); - - return timr; -} - -/** - * @brief Converts a date from timespec to RTC_CALR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the CALR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_date(const RTCDateTime *timespec) { - uint32_t n, calr = 0; - - /* Year conversion. */ - n = timespec->year + 1980; - calr = calr | ((n % 10) << RTC_CALR_YU_OFFSET); - n /= 10; - calr = calr | ((n % 10) << RTC_CALR_YT_OFFSET); - n /= 10; - calr = calr | ((n % 10) << RTC_CALR_CU_OFFSET); - n /= 10; - calr = calr | ((n % 10) << RTC_CALR_CT_OFFSET); - - /* Months conversion.*/ - n = timespec->month; - calr = calr | ((n % 10) << RTC_CALR_MU_OFFSET); - n /= 10; - calr = calr | ((n % 10) << RTC_CALR_MT_OFFSET); - - /* Days conversion.*/ - n = timespec->day; - calr = calr | ((n % 10) << RTC_CALR_DU_OFFSET); - n /= 10; - calr = calr | ((n % 10) << RTC_CALR_DT_OFFSET); - - /* Days of week conversion.*/ - calr = calr | (timespec->dayofweek << RTC_CALR_WDU_OFFSET); - - return calr; -} - -#if RTC_HAS_STORAGE -/* TODO: Map on the backup SRAM on devices that have it.*/ -static size_t _write(void *instance, const uint8_t *bp, size_t n) { - - (void)instance; - (void)bp; - (void)n; - - return 0; -} - -static size_t _read(void *instance, uint8_t *bp, size_t n) { - - (void)instance; - (void)bp; - (void)n; - - return 0; -} - -static msg_t _put(void *instance, uint8_t b) { - - (void)instance; - (void)b; - - return FILE_OK; -} - -static msg_t _get(void *instance) { - - (void)instance; - - return FILE_OK; -} - -static msg_t _close(void *instance) { - - /* Close is not supported.*/ - (void)instance; - - return FILE_OK; -} - -static msg_t _geterror(void *instance) { - - (void)instance; - - return (msg_t)0; -} - -static msg_t _getsize(void *instance) { - - (void)instance; - - return 0; -} - -static msg_t _getposition(void *instance) { - - (void)instance; - - return 0; -} - -static msg_t _lseek(void *instance, fileoffset_t offset) { - - (void)instance; - (void)offset; - - return FILE_OK; -} - -/** - * @brief VMT for the RTC storage file interface. - */ -struct RTCDriverVMT _rtc_lld_vmt = { - _write, _read, _put, _get, - _close, _geterror, _getsize, _getposition, _lseek -}; -#endif /* RTC_HAS_STORAGE */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Enable access to registers. - * - * @notapi - */ -void rtc_lld_init(void) { - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_SYSC, SECURE_PER); -#endif - - /* RTC object initialization.*/ - rtcObjectInit(&RTCD0); - - /* RTC pointer initialization.*/ - RTCD0.rtc = RTC; - - /* Disable write protection */ -// syscDisableWP(); - - RTCD0.rtc->RTC_IDR = RTC_IDR_ALRDIS | RTC_IDR_SECDIS; - - /* Clear all status flag.*/ - RTCD0.rtc->RTC_SCCR = 0x3F; - - /* Disable match alarms */ - RTCD0.rtc->RTC_TIMALR &= ~(RTC_TIMALR_SECEN | RTC_TIMALR_MINEN | RTC_TIMALR_HOUREN); - RTCD0.rtc->RTC_CALALR &= ~(RTC_CALALR_MTHEN | RTC_CALALR_DATEEN); - - /* Callback initially disabled.*/ - RTCD0.callback = NULL; - - /* Enable write protection */ -// syscEnableWP(); - - /* IRQ vector permanently assigned to this driver.*/ - aicSetSourcePriority(ID_SYSC, SAMA_RTC_IRQ_PRIORITY); - aicSetSourceHandler(ID_SYSC, SAMA_RTC_HANDLER); - aicEnableInt(ID_SYSC); -} - -/** - * @brief Set current time. - * @note Fractional part will be silently ignored. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { - uint32_t calr, timr, ver; - syssts_t sts; - - timr = rtc_encode_time(timespec); - calr = rtc_encode_date(timespec); - ver = rtcp->rtc->RTC_VER; - - /* Disable write protection */ -// syscDisableWP(); - - /* Synchronization on a second periodic event polling the RTC_SR.SEC status bit */ - wait: while ((rtcp->rtc->RTC_SR & RTC_SR_SEC) == 0); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (!(rtcp->rtc->RTC_SR & RTC_SR_SEC)) { - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - goto wait; - } - - /* Writing the registers.*/ - rtc_enter_init(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - while ((RTCD0.rtc->RTC_SR & RTC_SR_ACKUPD) == 0); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (!(rtcp->rtc->RTC_SR & RTC_SR_SEC)) { - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - goto wait; - } - - /* Clear ACKUPD status flag */ - rtcp->rtc->RTC_SCCR = RTC_SCCR_ACKCLR; - - /* Date and Time updating */ - rtcp->rtc->RTC_TIMR = timr; - rtcp->rtc->RTC_CALR = calr; - - rtc_exit_init(); - - /* Enable write protection */ -// syscEnableWP(); - - /* Check time and data fields */ - osalDbgAssert(((ver & RTC_VER_NVCAL) == 0) || ((ver & RTC_VER_NVTIM) == 0), - "invalid date-time"); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get current time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { - uint32_t calr, timr; - uint32_t subs = 0; - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - do { - timr = rtcp->rtc->RTC_TIMR; - } while (timr != rtcp->rtc->RTC_TIMR); - - do { - calr = rtcp->rtc->RTC_CALR; - } while (calr != rtcp->rtc->RTC_CALR); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - rtc_decode_time(timr, timespec); - timespec->millisecond += subs; - - /* Decoding date, this concludes the atomic read sequence.*/ - rtc_decode_date(calr, timespec); - - /* Retrieving the DST bit.*/ - timespec->dstflag = 0; -} - -/** - * @brief Get tamper time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] reg number of register to return - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @note RTC_TSSR0 and RTC_TSDR cannot be overwritten, so once it has been written - * all data are stored until the registers are reset: these register are - * storing the first tamper occurrence after a read. - * RTC_TSSR0 and RTC_TSDR are overwritten each time a tamper event is detected. - * - */ -void rtcGetTamperTime(RTCDriver *rtcp, uint8_t reg, RTCDateTime *timespec) { - uint32_t calr, timr; - uint32_t subs = 0; - - timr = rtcp->rtc->RTC_TS[reg].RTC_TSTR; - calr = rtcp->rtc->RTC_TS[reg].RTC_TSDR; - - rtc_decode_time(timr, timespec); - timespec->millisecond += subs; - - /* Decoding date, this concludes the atomic read sequence.*/ - rtc_decode_date(calr, timespec); - - /* Retrieving the DST bit.*/ - timespec->dstflag = 0; -} - -/** - * @brief Returns source of tamper register. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] reg number of register source to return - * - * return content of RTC_SSRx register - * - * @note RTC_TSSR0 cannot be overwritten, so once it has been written - * all data are stored until the registers are reset: that register is - * storing the first tamper occurrence after a read. - * RTC_TSSR1 is overwritten each time a tamper event is detected. - * - */ -uint32_t rtcGetTamperSource(RTCDriver *rtcp, uint8_t reg) { - return ((rtcp)->rtc->RTC_TS[reg].RTC_TSSR); -} - -/** - * @brief Returns numbers of total tamper events. - * - * @param[in] rtcp pointer to RTC driver structure - * - * return numbers of total tamper events. - */ -uint32_t rtcGetTamperEventCounter(RTCDriver *rtcp) { - return ((rtcp)->rtc->RTC_TS[0].RTC_TSTR & RTC_TSTR_TEVCNT_Msk) >> RTC_TSTR_TEVCNT_Pos; -} - -/** - * @brief Returns backup or normal mode of tamper event. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] reg number of register source to return - * - * @return 0x1 if system is in backup mode when tamper events occurs - * 0x0 if system is not in backup mode when tamper events occurs - * - * @note RTC_TSTR0 cannot be overwritten, so once it has been written - * all data are stored until the registers are reset: that register is - * storing the first tamper occurrence after a read. - * RTC_TSTR1 is overwritten each time a tamper event is detected. - * - */ -uint8_t rtcGetTamperMode(RTCDriver *rtcp, uint8_t reg) { - return (rtcp)->rtc->RTC_TS[reg].RTC_TSTR & RTC_TSTR_BACKUP ? 0x1u : 0x0u; -} - -/** - * @brief Set alarm time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] alarm alarm identifier. - * @param[in] alarmspec pointer to a @p RTCAlarm structure. - * - * @notapi - */ -void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec) { - - /* SAMA has only one alarm, this field is ignored */ - (void)alarm; - syssts_t sts; - - /* Disable write protection */ -// syscDisableWP(); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (alarmspec != NULL) { - if (alarmspec->timralrm != 0){ - rtcp->rtc->RTC_TIMALR = alarmspec->timralrm; - /* Check time alarm fields */ - osalDbgAssert(((rtcp->rtc->RTC_VER & RTC_VER_NVTIMALR) == 0), - "invalid time-alarm"); - } - if (alarmspec->calralrm != 0){ - rtcp->rtc->RTC_CALALR = alarmspec->calralrm; - /* Check calendar alarm fields */ - osalDbgAssert(((rtcp->rtc->RTC_VER & RTC_VER_NVCALALR) == 0), - "invalid date-alarm"); - } - } - else { - rtcp->rtc->RTC_TIMALR = 0; - rtcp->rtc->RTC_CALALR = 0; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - /* Enable write protection */ -// syscEnableWP(); -} - -/** - * @brief Get alarm time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier - * @param[out] alarmspec pointer to a @p RTCAlarm structure - * - * @notapi - */ -void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec) { - - (void)alarm; - alarmspec->timralrm = rtcp->rtc->RTC_TIMALR; - alarmspec->calralrm = rtcp->rtc->RTC_CALALR; -} - -/** - * @brief Enables or disables RTC callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] callback callback function pointer or @p NULL - * - * @notapi - */ -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (callback != NULL) { - - /* IRQ sources enabled only after setting up the callback.*/ - rtcp->callback = callback; - - rtcp->rtc->RTC_SCCR = RTC_SCCR_ALRCLR | RTC_SCCR_SECCLR | RTC_SCCR_TIMCLR | - RTC_SCCR_CALCLR | RTC_SCCR_TDERRCLR; - rtcp->rtc->RTC_IER = RTC_IER_ALREN | RTC_IER_SECEN; - } - else { - rtcp->rtc->RTC_IDR = RTC_IDR_ALRDIS | RTC_IDR_SECDIS; - - /* Callback set to NULL only after disabling the IRQ sources.*/ - rtcp->callback = NULL; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -#endif /* HAL_USE_RTC */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.h b/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.h deleted file mode 100644 index 7b5fb3cd2..000000000 --- a/os/hal/ports/SAMA/LLD/RTCv1/hal_rtc_lld.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv1/hal_rtc_lld.h - * @brief SAMA RTC low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#ifndef HAL_RTC_LLD_H -#define HAL_RTC_LLD_H - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ -#define SYSC_WPMR (0xF80480E4u) -#define SYSC_WPMR_WPKEY_PASSWD (0x535943u << 8) -#define SYSC_WPMR_WPEN (0x1u << 0) - -/** - * @name Implementation capabilities - */ -/** - * @brief Number of available alarms. - */ -#define RTC_ALARMS 1 - -/** - * @brief Presence of a local persistent storage. - */ -#define RTC_HAS_STORAGE FALSE - -/** - * @brief Callback supported. - */ -#define RTC_SUPPORTS_CALLBACKS TRUE -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/* - * RTC driver system settings. - */ -#define SAMA_RTC_IRQ_PRIORITY 7 -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an RTC event. - */ -typedef enum { - RTC_EVENT_SECOND = 0, /** Triggered every second. */ - RTC_EVENT_ALARM = 1 /** Triggered on alarm. */ -} rtcevent_t; - -/** - * @brief Type of a generic RTC callback. - */ -typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); - -/** - * @brief Type of a structure representing an RTC alarm time stamp. - */ -typedef struct hal_rtc_alarm { - /** - * @brief Type of an alarm as encoded in RTC registers. - */ - uint32_t timralrm; - uint32_t calralrm; -} RTCAlarm; - -/** - * @brief Implementation-specific @p RTCDriver fields. - */ -#define rtc_lld_driver_fields \ - /* Pointer to the RTC registers block.*/ \ - Rtc *rtc; \ - /* Callback pointer.*/ \ - rtccb_t callback - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @brief Enable write protection on SYSC registers block. - * - * @notapi - */ -#define syscEnableWP() { \ - *(uint32_t *)(SYSC_WPMR) = SYSC_WPMR_WPKEY_PASSWD | SYSC_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on SYSC registers block. - * - * @notapi - */ -#define syscDisableWP() { \ - *(uint32_t *)(SYSC_WPMR) = SYSC_WPMR_WPKEY_PASSWD; \ -} - -/** - * @brief Configure RTC_MR register. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] value value to be written in the MR register - * - */ -#define rtcConfigureMode(rtcp, value) { \ - (rtcp)->rtc->RTC_MR = value; \ -} - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void rtc_lld_init(void); - void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); - void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); - void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec); - void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec); - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); - /* Driver specific */ - void rtcGetTamperTime(RTCDriver *rtcp, uint8_t reg, RTCDateTime *timespec); - uint32_t rtcGetTamperSource(RTCDriver *rtcp, uint8_t reg); - uint32_t rtcGetTamperEventCounter(RTCDriver *rtcp); - uint8_t rtcGetTamperMode(RTCDriver *rtcp, uint8_t reg); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_RTC */ - -#endif /* HAL_RTC_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.c b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.c deleted file mode 100644 index d019da05a..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.c +++ /dev/null @@ -1,512 +0,0 @@ -#include -#include "hal.h" - -#if (SAMA_USE_SDMMC == TRUE) - -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_cmds.h" -#include "ch_sdmmc_sdio.h" -#include "ch_sdmmc_sd.h" -#include "ch_sdmmc_mmc.h" - -/** SD/MMC transfer rate unit codes (10K) list */ -const uint16_t sdmmcTransUnits[8] = { - 10, 100, 1000, 10000, - 0, 0, 0, 0 -}; - -/** SD transfer multiplier factor codes (1/10) list */ -const uint8_t sdTransMultipliers[16] = { - 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 -}; - - - -uint32_t SdmmcGetMaxFreq(SdmmcDriver *drv) -{ - uint32_t rate = 0; - sSdCard * pSd = &drv->card; - -#ifndef SDMMC_TRIM_MMC - if ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC) { - if (pSd->bSpeedMode == SDMMC_TIM_MMC_HS200) - rate = 200000ul; - else if (pSd->bSpeedMode == SDMMC_TIM_MMC_HS_DDR - || (pSd->bSpeedMode == SDMMC_TIM_MMC_HS_SDR - && MMC_EXT_CARD_TYPE(pSd->EXT) & 0x2)) - rate = 52000ul; - else if (pSd->bSpeedMode == SDMMC_TIM_MMC_HS_SDR) - rate = 26000ul; - else - rate = SdmmcDecodeTransSpeed(SD_CSD_TRAN_SPEED(pSd->CSD), - sdmmcTransUnits, mmcTransMultipliers); - } -#endif - - if ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD) { - rate = SdmmcDecodeTransSpeed(SD_CSD_TRAN_SPEED(pSd->CSD), - sdmmcTransUnits, sdTransMultipliers); - if (pSd->bSpeedMode == SDMMC_TIM_SD_SDR104 && rate == 200000ul) - rate = 208000ul; - else if (pSd->bSpeedMode == SDMMC_TIM_SD_DDR50) - rate /= 2ul; - } - - TRACE_DEBUG_1("SdmmcGetMaxFreq rate %d\r\n",rate); - return rate * 1000ul; -} - - - -/** - * Update SD/MMC information. - * Update CSD for card speed switch. - * Update ExtDATA for any card function switch. - * \param pSd Pointer to a SD card driver instance. - * \return error code when update CSD error. - */ -void SdMmcUpdateInformation(SdmmcDriver *drv, bool csd, bool extData) -{ - uint8_t error; - - /* Update CSD for new TRAN_SPEED value */ - if (csd) { - - SdMmcSelect(drv, 0, 1); - - /* Wait for 14 usec (or more) */ - t_usleep(drv,20); - - error = Cmd9(drv); - - if (error) - return; - - SdMmcSelect(drv, drv->card.wAddress, 1); - } - if (extData) { - if ((drv->card.bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD) - SdGetExtInformation(drv); -#ifndef SDMMC_TRIM_MMC - else if ((drv->card.bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC) - MmcGetExtInformation(drv); -#endif - } -} - - -uint8_t SDMMC_Lib_SdStart(SdmmcDriver *drv, bool * retry) -{ - uint64_t mem_size; - uint32_t freq; - uint32_t drv_err, status; - uint8_t error; - bool flag; - sSdCard *pSd = &drv->card; - - *retry = false; - - drv->card.bSpeedMode = drv->card.bCardSigLevel == 0 ? SDMMC_TIM_SD_SDR12 : SDMMC_TIM_SD_DS; - drv->timeout_elapsed = -1; - HwSetHsMode(drv, drv->card.bSpeedMode); - - /* Consider switching to low signaling level, as a prerequisite to - * switching to any UHS-I timing mode */ - if (drv->card.bCardSigLevel == 1) { - - error = Cmd11(drv, &status); - - if (error) - return error; - - if ((status & STATUS_STATE) != STATUS_READY) { - TRACE_1("st %lx\n\r", status); - } - - drv->card.bCardSigLevel = 0; - error = HwPowerDevice(drv, SDMMC_PWR_STD_VDD_LOW_IO); - - if (error) - return error; - - error = HwSetHsMode(drv, SDMMC_TIM_SD_SDR12); - - if (error) - return error; - - drv->card.bSpeedMode = SDMMC_TIM_SD_SDR12; - } - - /* The host then issues the command ALL_SEND_CID (CMD2) to the card to get - * its unique card identification (CID) number. - * Card that is unidentified (i.e. which is in Ready State) sends its CID - * number as the response (on the CMD line). */ - error = Cmd2(drv); - if (error) - return error; - - /* Thereafter, the host issues CMD3 (SEND_RELATIVE_ADDR) asks the - * card to publish a new relative card address (RCA), which is shorter than - * CID and which is used to address the card in the future data transfer - * mode. Once the RCA is received the card state changes to the Stand-by - * State. At this point, if the host wants to assign another RCA number, it - * can ask the card to publish a new number by sending another CMD3 command - * to the card. The last published RCA is the actual RCA number of the - * card. */ - error = Cmd3(drv); - if (error) - return error; - else { - TRACE_DEBUG_1("RCA=%u\n\r",drv->card.wAddress ); - } - - /* SEND_CSD (CMD9) to obtain the Card Specific Data (CSD register), - * e.g. block length, card storage capacity, etc... */ - error = Cmd9(drv); - if (error) - return error; - - /* Now select the card, to TRAN state */ - error = SdMmcSelect(drv, drv->card.wAddress , 0); - if (error) - return error; - - /* Get extended information of the card */ - SdMmcUpdateInformation(drv, true, true); - - /* Enable more bus width Mode */ - error = SdDecideBuswidth(drv); - if (error) { - //trace_error("Bus width %s\n\r", SD_StringifyRetCode(error)); - return SDMMC_ERR; - } - - /* Consider HS and UHS-I timing modes */ - error = SdEnableHighSpeed(drv); - if (error) { - *retry = error == (SDMMC_STATE && (&drv->card.bCardSigLevel != 0)); - return error; - } - - /* Update card information since status changed */ - flag = drv->card.bSpeedMode != SDMMC_TIM_SD_DS - && drv->card.bSpeedMode != SDMMC_TIM_SD_SDR12; - if (flag || drv->card.bBusMode > 1) - SdMmcUpdateInformation(drv, flag, true); - - /* Find out if the device supports the SET_BLOCK_COUNT command. - * SD devices advertise in SCR.CMD_SUPPORT whether or not they handle - * the SET_BLOCK_COUNT command. */ - drv->card.bSetBlkCnt = SD_SCR_CMD23_SUPPORT(pSd->SCR); - /* Now, if the device does not support the SET_BLOCK_COUNT command, then - * the legacy STOP_TRANSMISSION command shall be issued, though not at - * the same timing. */ - if (!drv->card.bSetBlkCnt) { - /* In case the driver does not automatically issue the - * STOP_TRANSMISSION command, we'll have to do it ourselves. */ - - drv->control_param = 0; - drv_err = sdmmc_device_control(drv, SDMMC_IOCTL_GET_XFERCOMPL); - - if (drv_err != SDMMC_OK || !drv->control_param) - drv->card.bStopMultXfer = 1; - } - /* Ask the driver to implicitly send the SET_BLOCK_COUNT command, - * immediately before every READ_MULTIPLE_BLOCK and WRITE_MULTIPLE_BLOCK - * command. Or, if the current device does not support SET_BLOCK_COUNT, - * instruct the driver to stop using this command. */ - drv->control_param = pSd->bSetBlkCnt; - - drv_err = sdmmc_device_control(drv,SDMMC_IOCTL_SET_LENPREFIX); - - /* In case the driver does not support this function, we'll take it in - * charge. */ - if (drv->card.bSetBlkCnt && drv_err == SDMMC_OK && drv->control_param) - drv->card.bSetBlkCnt = 0; - - /* In the case of a Standard Capacity SD Memory Card, this command sets the - * block length (in bytes) for all following block commands - * (read, write, lock). - * Default block length is fixed to 512 Bytes. - * Set length is valid for memory access commands only if partial block read - * operation are allowed in CSD. - * In the case of a High Capacity SD Memory Card, block length set by CMD16 - * command does not affect the memory read and write commands. Always 512 - * Bytes fixed block length is used. This command is effective for - * LOCK_UNLOCK command. - * In both cases, if block length is set larger than 512Bytes, the card sets - * the BLOCK_LEN_ERROR bit. */ - if (drv->card.bCardType == CARD_SD) { - error = Cmd16(drv, SDMMC_BLOCK_SIZE); - if (error) - return error; - } - drv->card.wCurrBlockLen = SDMMC_BLOCK_SIZE; - - if (SD_CSD_STRUCTURE(pSd->CSD) >= 1) { - drv->card.wBlockSize = 512; - mem_size = SD_CSD_BLOCKNR_HC(pSd->CSD); - drv->card.dwNbBlocks = mem_size >> 32 ? 0xFFFFFFFF : (uint32_t)mem_size; - if (drv->card.dwNbBlocks >= 0x800000) - drv->card.dwTotalSize = 0xFFFFFFFF; - else - drv->card.dwTotalSize = drv->card.dwNbBlocks * 512UL; - } - else { - drv->card.wBlockSize = 512; - mem_size = SD_CSD_TOTAL_SIZE(pSd->CSD); - drv->card.dwNbBlocks = (uint32_t)(mem_size >> 9); - drv->card.dwTotalSize = mem_size >> 32 ? 0xFFFFFFFF - : (uint32_t)mem_size; - } - - - /* Automatically select the max device clock frequency */ - /* Calculate transfer speed */ - freq = SdmmcGetMaxFreq(drv); - -#ifndef SDMMC_TRIM_SDIO - if (drv->card.bCardType & CARD_TYPE_bmSDIO) { - freq = min_u32(freq, SdioGetMaxFreq(drv)); - TRACE_INFO_1("selecting sdio freq%d\r\n",freq); - } -#endif - error = HwSetClock(drv, &freq); - drv->card.dwCurrSpeed = freq; - if (error != SDMMC_OK && error != SDMMC_CHANGED) { - TRACE_ERROR_1("error clk %s\n\r", SD_StringifyRetCode(error)); - return error; - } - - /* Check device status and eat past exceptions, which would otherwise - * prevent upcoming data transaction routines from reliably checking - * fresh exceptions. */ - error = Cmd13(drv, &status); - if (error) - return error; - status = status & ~STATUS_STATE & ~STATUS_READY_FOR_DATA & ~STATUS_APP_CMD; - - //warning - if (status) { - TRACE_WARNING_1("warning st %lx\n\r", status); - } - - return SDMMC_OK; -} - - - -/** - * \brief Run the SD/MMC/SDIO Mode initialization sequence. - * This function runs the initialization procedure and the identification - * process. Then it leaves the card in ready state. The following procedure must - * check the card type and continue to put the card into tran(for memory card) - * or cmd(for io card) state for data exchange. - * \param pSd Pointer to a SD card driver instance. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "SD_ERROR code". - */ -uint8_t SdMmcIdentify(SdmmcDriver *drv) -{ - uint8_t error; - bool high_capacity; - uint8_t dev_type = CARD_UNKNOWN; - bool sd_v2 = false; - - -#ifndef SDMMC_TRIM_SDIO - /* Reset SDIO: CMD52, write 1 to RES bit in CCCR */ - { - uint32_t status = SDIO_RES; - - error = Cmd52(drv, 1, SDIO_CIA, 0, SDIO_IOA_REG, &status); - - if ((error && error != SDMMC_NO_RESPONSE) || (!error && status & STATUS_SDIO_R5)) { - TRACE_2("IOrst %s st %lx\n\r", - SD_StringifyRetCode(error), status); - } - } -#endif - - - /* Reset MEM: CMD0 */ - error = Cmd0(drv, 0); - - t_msleep(drv,200); - - if (error) { - TRACE_1("rst %s\n\r", SD_StringifyRetCode(error)); - } - - - /* CMD8 is newly added in the Physical Layer Specification Version 2.00 to - * support multiple voltage ranges and used to check whether the card - * supports supplied voltage. The version 2.00 host shall issue CMD8 and - * verify voltage before card initialization. - * The host that does not support CMD8 shall supply high voltage range... */ - - - error = SdCmd8(drv, SD_IFC_VHS_27_36 >> SD_IFC_VHS_Pos); - - if (!error) - sd_v2 = true; - else if (error != SDMMC_NO_RESPONSE) - return SDMMC_ERR; - else { - /* No response to CMD8. Wait for 130 usec (or more). */ - t_usleep(drv,200); - } - - -#ifndef SDMMC_TRIM_SDIO - /* CMD5 is newly added for SDIO initialize & power on */ - { - uint32_t status = 0; - - error = Cmd5(drv, &status); - - if (!error && (status & SDIO_OCR_NF) > 0) { - - //int8_t elapsed; - - /* Card has SDIO function. Wait until it raises the - * IORDY flag, which may take up to 1s, i.e. 1000 system - * ticks. */ - for (drv->timeout_elapsed = 0; - !(status & SD_OCR_BUSYN) && !error && !drv->timeout_elapsed; ) { - - - status &= SD_HOST_VOLTAGE_RANGE; - error = Cmd5(drv, &status); - } - if (!(status & SD_OCR_BUSYN) && !error) - error = SDMMC_BUSY; - if (error) { - TRACE_1("SDIO oc %s\n\r",SD_StringifyRetCode(error)); - return SDMMC_ERR; - } - TRACE("SDIO\n\r"); - dev_type = status & SDIO_OCR_MP ? CARD_SDCOMBO : CARD_SDIO; - } - } -#endif - - if (dev_type != CARD_SDIO) { - /* The device should have memory (MMC or SD or COMBO). - * Try to initialize SD memory. */ - bool low_sig_lvl = HwIsTimingSupported(drv, SDMMC_TIM_SD_SDR12); - - high_capacity = sd_v2; - error = Acmd41(drv, &low_sig_lvl, &high_capacity); - if (!error) { - TRACE_1("SD%s MEM\n\r", high_capacity ? "HC" : ""); - dev_type |= high_capacity ? CARD_SDHC : CARD_SD; - if (drv->card.bCardSigLevel == 2 && low_sig_lvl) - drv->card.bCardSigLevel = 1; - } - else if (dev_type == CARD_SDCOMBO) - dev_type = CARD_SDIO; - } - -#ifndef SDMMC_TRIM_MMC - if (dev_type == CARD_UNKNOWN) { - /* Try MMC initialize */ - uint8_t count; - - for (error = SDMMC_NO_RESPONSE, count = 0; - error == SDMMC_NO_RESPONSE && count < 10; - count++) - error = Cmd0(drv, 0); - if (error) { - TRACE_1("MMC rst %s\n\r", - SD_StringifyRetCode(error)); - return SDMMC_ERR; - } - high_capacity = false; - error = Cmd1(drv, &high_capacity); - if (error) { - TRACE_1("MMC oc %s\n\r", - SD_StringifyRetCode(error)); - return SDMMC_ERR; - } - /* MMC card identification OK */ - TRACE("MMC\n\r"); - dev_type = high_capacity ? CARD_MMCHD : CARD_MMC; - } -#endif - - if (dev_type == CARD_UNKNOWN) { - TRACE("Unknown card\n\r"); - return SDMMC_ERR; - } - drv->card.bCardType = dev_type; - return 0; -} - - - -/** - * Switch card state between STBY and TRAN (or CMD and TRAN) - * \param pSd Pointer to a SD card driver instance. - * \param address Card address to TRAN, 0 to STBY - * \param statCheck Whether to check the status before CMD7. - */ -uint8_t SdMmcSelect(SdmmcDriver *drv, uint16_t address, uint8_t statCheck) -{ - uint8_t error; - uint32_t status, currState; - uint32_t targetState = address ? STATUS_TRAN : STATUS_STBY; - uint32_t srcState = address ? STATUS_STBY : STATUS_TRAN; - - /* At this stage the Initialization and identification process is achieved - * The SD card is supposed to be in Stand-by State */ - while (statCheck) { - error = Cmd13(drv, &status); - if (error) - return error; - if (status & STATUS_READY_FOR_DATA) { - currState = status & STATUS_STATE; - if (currState == targetState) - return 0; - if (currState != srcState) { - TRACE_ERROR_1("st %lx\n\r", currState); - return SDMMC_ERR; - } - break; - } - } - - /* Switch to Transfer state. Select the current SD/MMC - * so that SD ACMD6 can process or EXT_CSD can read. */ - error = Cmd7(drv, address); - return error; -} - -/** - * \brief Decode Trans Speed Value - * \param code The trans speed code value. - * \param unitCodes Unit list in 10K, 0 as unused value. - * \param multiCodes Multiplier list in 1/10, index 1 ~ 15 is valid. - */ -uint32_t SdmmcDecodeTransSpeed(uint32_t code, - const uint16_t * unitCodes, const uint8_t * multiCodes) -{ - uint32_t speed; - uint8_t unitI, mulI; - - /* Unit code is valid ? */ - unitI = code & 0x7; - if (unitCodes[unitI] == 0) - return 0; - - /* Multi code is valid ? */ - mulI = (code >> 3) & 0xF; - if (multiCodes[mulI] == 0) - return 0; - - speed = (uint32_t)unitCodes[unitI] * multiCodes[mulI]; - return speed; -} - -#endif - diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.h deleted file mode 100644 index 2370d36a9..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef _CH_SDMMC_LIB_H -#define _CH_SDMMC_LIB_H - -#include "sama_sdmmc_conf.h" - - -/** - * \brief SD/MMC card driver structure. - * It holds the current command being processed and the SD/MMC card address. - * - * The first members of this structure may have to follow the DMA alignment - * requirements. - */ -typedef struct _SdCard { - - - uint8_t *EXT; /**< MMC Extended Device-Specific Data Register - * (EXT_CSD). This member may have to follow - * the DMA alignment requirements. */ - uint8_t *SSR; /**< SD Status Register (SSR). - * This member may have to follow the DMA - * alignment requirements. */ - uint8_t *SCR; /**< SD CARD Configuration Register (SCR). - * This member may have to follow the DMA - * alignment requirements. */ - uint8_t *sandbox1; /**< Multi-purpose temporary buffer. - * This member may have to follow the DMA - * alignment requirements. */ - uint8_t *sandbox2; /**< Multi-purpose temporary buffer. - * This member may have to follow the DMA - * alignment requirements. */ - - uint32_t CID[128 / 8 / 4]; /**< Card Identification (CID register) */ - uint32_t CSD[128 / 8 / 4]; /**< Card-specific data (CSD register) */ - - void *pExt; /**< Pointer to extension data for SD/MMC/SDIO */ - - uint32_t dwTotalSize; /**< Card total size - (0xffffffff to see number of blocks */ - uint32_t dwNbBlocks; /**< Card total number of blocks */ - uint16_t wBlockSize; /**< Card block size reported */ - - uint16_t wCurrBlockLen; /**< Block length used */ - uint32_t dwCurrSpeed; /**< Device clock frequency used, in Hz */ - uint16_t wAddress; /**< Current card address */ - uint8_t bCardType; /**< SD/MMC/SDIO card type \sa sdmmc_cardtype */ - uint8_t bCardSigLevel; /**< 0/1/2 for low/ready_for_low/high signaling - * level used by the card, respectively. */ - uint8_t bSpeedMode; /**< Timing mode */ - uint8_t bBusMode; /**< 1/4/8 bit data bus mode */ - - uint8_t bStatus; /**< Unrecovered error */ - uint8_t bSetBlkCnt; /**< Explicit SET_BLOCK_COUNT command used */ - uint8_t bStopMultXfer; /**< Explicit STOP_TRANSMISSION command used */ -} sSdCard; - - -/** - * Sdmmc command operation settings union. - */ -typedef union _SdmmcCmdOperation { - uint16_t wVal; - struct _SdmmcOpBm { - uint16_t powerON:1, /**< Do power on initialize */ - sendCmd:1, /**< Send SD/MMC command */ - xfrData:2, /**< Send/Stop data transfer */ - respType:3, /**< Response type (1~7) */ - crcON:1, /**< CRC is used (SPI) */ - odON:1, /**< Open-Drain is ON (MMC) */ - ioCmd:1, /**< SDIO command */ - checkBsy:1; /**< Busy check is ON */ - } bmBits; -} uSdmmcCmdOp; - -/** - * Sdmmc command instance. - */ -typedef struct _SdmmcCommand { - - /** Optional user-provided callback function. */ - //fSdmmcCallback fCallback; - /** Optional argument to the callback function. */ - void *pArg; - - /** Data buffer. It shall follow the peripheral and DMA alignment - * requirements, which are peripheral and driver dependent. */ - uint8_t *pData; - /** Size of data block in bytes. */ - uint16_t wBlockSize; - /** Number of blocks to be transfered */ - uint16_t wNbBlocks; - /** Response buffer. */ - uint32_t *pResp; - - /** Command argument. */ - uint32_t dwArg; - /** Command operation settings */ - uSdmmcCmdOp cmdOp; - /** Command index */ - uint8_t bCmd; - /** Command return status */ - volatile uint8_t bStatus; -} sSdmmcCommand; - - -/** SD/MMC Return codes */ -typedef enum { - SDMMC_OK = 0, /**< Operation OK */ - SDMMC_LOCKED = 1, /**< Failed because driver locked */ - SDMMC_BUSY = 2, /**< Failed because driver busy */ - SDMMC_NO_RESPONSE = 3, /**< Failed because card not respond */ - SDMMC_CHANGED, /**< Setting param changed due to limitation */ - SDMMC_ERR, /**< Failed with general error */ - SDMMC_ERR_IO, /**< Failed because of IO error */ - SDMMC_ERR_RESP, /**< Error reported in response code */ - SDMMC_NOT_INITIALIZED, /**< Fail to initialize */ - SDMMC_PARAM, /**< Parameter error */ - SDMMC_STATE, /**< State error */ - SDMMC_USER_CANCEL, /**< Canceled by user */ - SDMMC_NOT_SUPPORTED /**< Command(Operation) not supported */ -} eSDMMC_RC; - -/** - * \addtogroup sdmmc_cardtype SD/MMC Card Types - * Here lists the SD/MMC card types. - * - Card Type Category Bitmap - * - \ref CARD_TYPE_bmHC - * - \ref CARD_TYPE_bmSDMMC - * - \ref CARD_TYPE_bmUNKNOWN - * - \ref CARD_TYPE_bmSD - * - \ref CARD_TYPE_bmMMC - * - \ref CARD_TYPE_bmSDIO - * - Card Types - * - \ref CARD_UNKNOWN - * - \ref CARD_SD - * - \ref CARD_SDHC - * - \ref CARD_MMC - * - \ref CARD_MMCHD - * - \ref CARD_SDIO - * - \ref CARD_SDCOMBO - * - \ref CARD_SDHCCOMBO - * @{*/ -#define CARD_TYPE_bmHC (1 << 0) /**< Bit for High-Capacity(Density) */ -#define CARD_TYPE_bmSDMMC (0x3 << 1) /**< Bits mask for SD/MMC */ -#define CARD_TYPE_bmUNKNOWN (0x0 << 1) /**< Bits for Unknown card */ -#define CARD_TYPE_bmSD (0x1 << 1) /**< Bits for SD */ -#define CARD_TYPE_bmMMC (0x2 << 1) /**< Bits for MMC */ -#define CARD_TYPE_bmSDIO (1 << 3) /**< Bit for SDIO */ -/** Card can not be identified */ -#define CARD_UNKNOWN (0) -/** SD Card (0x2) */ -#define CARD_SD (CARD_TYPE_bmSD) -/** SD High Capacity Card (0x3) */ -#define CARD_SDHC (CARD_TYPE_bmSD|CARD_TYPE_bmHC) -/** MMC Card (0x4) */ -#define CARD_MMC (CARD_TYPE_bmMMC) -/** MMC High-Density Card (0x5) */ -#define CARD_MMCHD (CARD_TYPE_bmMMC|CARD_TYPE_bmHC) -/** SDIO only card (0x8) */ -#define CARD_SDIO (CARD_TYPE_bmSDIO) -/** SDIO Combo, with SD embedded (0xA) */ -#define CARD_SDCOMBO (CARD_TYPE_bmSDIO|CARD_SD) -/** SDIO Combo, with SDHC embedded (0xB) */ -#define CARD_SDHCCOMBO (CARD_TYPE_bmSDIO|CARD_SDHC) - -#include "ch_sdmmc_macros.h" -#include "ch_sdmmc_trace.h" - -extern const uint16_t sdmmcTransUnits[8]; -extern const uint8_t sdTransMultipliers[16]; -extern const uint8_t mmcTransMultipliers[16]; -extern void SdParamReset(sSdCard * pSd); -extern uint32_t SdmmcDecodeTransSpeed(uint32_t code,const uint16_t * unitCodes, const uint8_t * multiCodes); - - - -#endif /*_CH_SDMMC_LIB_H*/ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.c b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.c deleted file mode 100644 index dbfa8bd7a..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.c +++ /dev/null @@ -1,1255 +0,0 @@ -#include -#include "hal.h" - -#if (SAMA_USE_SDMMC == TRUE) - -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_cmds.h" -#include "ch_sdmmc_sd.h" - - -/** sdmmc_opc_acc SD_SEND_OP_COND command argument fields - */ -#define SD_OPC_S18R (1ul << 24) /**< Switching to 1.8V signaling level Request */ -#define SD_OPC_XPC (1ul << 28) /**< SDXC Power Control */ -#define SD_OPC_FB (1ul << 29) /**< eSD Fast Boot */ -#define SD_OPC_HCS (1ul << 30) /**< Host Capacity Support */ -/** - * sdmmc_cmd_op SD/MMC Command Operations - */ -#define SDMMC_CMD_bmPOWERON (0x1 ) /**< Do Power ON sequence */ -#define SDMMC_CMD_bmCOMMAND (0x1 << 1) /**< Send command */ -#define SDMMC_CMD_bmDATAMASK (0x3 << 2) /**< Data operation mask */ -#define SDMMC_CMD_bmNODATA (0x0 << 2) /**< No data transfer */ -#define SDMMC_CMD_RX 0x1 /**< data RX */ -#define SDMMC_CMD_bmDATARX (0x1 << 2) /**< Bits for data RX */ -#define SDMMC_CMD_TX 0x2 /**< data TX */ -#define SDMMC_CMD_bmDATATX (0x2 << 2) /**< Bits for data TX */ -#define SDMMC_CMD_STOPXFR 0x3 /**< data stop */ -#define SDMMC_CMD_bmSTOPXFR (0x3 << 2) /**< Bits for transfer stop */ -#define SDMMC_CMD_bmRESPMASK (0x7 << 4) /**< Bits masks response option */ -#define SDMMC_CMD_bmRESP(R) (((R)&0x7) << 4) /**< Bits setup response type: 1 for R1, 2 for R2, ... 7 for R7 */ - -#define SDMMC_CMD_bmCRC (0x1 << 7) /**< CRC is enabled (SPI only) */ -#define SDMMC_CMD_bmOD (0x1 << 8) /**< Open-Drain is enabled (MMC) */ -#define SDMMC_CMD_bmIO (0x1 << 9) /**< IO function */ -#define SDMMC_CMD_bmBUSY (0x1 << 10) /**< Do busy check */ - -/** Cmd: Do power on initialize */ -#define SDMMC_CMD_POWERONINIT (SDMMC_CMD_bmPOWERON) -/** Cmd: Data only, read */ -#define SDMMC_CMD_DATARX (SDMMC_CMD_bmDATARX) -/** Cmd: Data only, write */ -#define SDMMC_CMD_DATATX (SDMMC_CMD_bmDATATX) -/** Cmd: Command without data */ -#define SDMMC_CMD_CNODATA(R) ( SDMMC_CMD_bmCOMMAND \ - | SDMMC_CMD_bmRESP(R) ) -/** Cmd: Command with data, read */ -#define SDMMC_CMD_CDATARX(R) ( SDMMC_CMD_bmCOMMAND \ - | SDMMC_CMD_bmDATARX \ - | SDMMC_CMD_bmRESP(R) ) -/** Cmd: Command with data, write */ -#define SDMMC_CMD_CDATATX(R) ( SDMMC_CMD_bmCOMMAND \ - | SDMMC_CMD_bmDATATX \ - | SDMMC_CMD_bmRESP(R) ) -/** Cmd: Send Stop command */ -#define SDMMC_CMD_CSTOP ( SDMMC_CMD_bmCOMMAND \ - | SDMMC_CMD_bmSTOPXFR \ - | SDMMC_CMD_bmRESP(1) ) -/** Cmd: Send Stop token for SPI */ -#define SDMMC_CMD_STOPTOKEN (SDMMC_CMD_bmSTOPXFR) - - -#define STATUS_MMC_SWITCH ((uint32_t)( STATUS_CARD_IS_LOCKED \ - | STATUS_COM_CRC_ERROR \ - | STATUS_ILLEGAL_COMMAND \ - | STATUS_CC_ERROR \ - | STATUS_ERROR \ - | STATUS_ERASE_RESET \ - /*| STATUS_STATE*/ \ - /*| STATUS_READY_FOR_DATA*/ \ - | STATUS_SWITCH_ERROR )) - - -static void _ResetCmd(sSdmmcCommand * pCmd); - -/** - * Initialization delay: The maximum of 1 msec, 74 clock cycles and supply ramp - * up time. - * Returns the command transfer result (see SendMciCommand). - */ -uint8_t CmdPowerOn(SdmmcDriver *drv) -{ - //sSdmmcCommand *pCmd = &pSd->sdCmd; - uint8_t bRc; - - TRACE("PwrON\n\r"); - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.cmdOp.wVal = SDMMC_CMD_POWERONINIT; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - - - return bRc; -} - - - - - -/** - * Resets all cards to idle state - * \param drv Pointer to \ref SdmmcDriver instance. - * \param arg Argument used. - * \return the command transfer result (see SendMciCommand). - */ -uint8_t Cmd0(SdmmcDriver *drv, uint8_t arg) -{ - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(0); - drv->cmd.dwArg = arg; - drv->timeout_elapsed = -1; - bRc = sdmmcSendCmd(drv); - - - return bRc; -} - -/** - * MMC send operation condition command. - * Sends host capacity support information and activates the card's - * initialization process. - * Returns the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param hc Upon success tells whether the device is a high capacity device. - */ -#ifndef SDMMC_TRIM_MMC -uint8_t Cmd1(SdmmcDriver *drv, bool * hc) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint32_t arg, ocr = 0; - uint8_t rc; - //int8_t elapsed = -1; - - /* Tell the device that the host supports 512-byte sector addressing */ - arg = MMC_OCR_ACCESS_SECTOR; - /* Tell the MMC device which voltage the host supplies to the VDD line - * (MMC card) or VCC line (e.MMC device). - * TODO get this board-specific value from platform code. On the - * SAMA5D2-XULT board, VDD is 3.3V � 1%. */ - arg |= SD_OCR_VDD_32_33 | SD_OCR_VDD_33_34; - - /* Fill command */ - _ResetCmd(&drv->cmd); - - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(3) | SDMMC_CMD_bmOD; - pCmd->bCmd = 1; - pCmd->dwArg = arg; - pCmd->pResp = &ocr; - - drv->timeout_ticks = TIME_S2I(1); - drv->timeout_elapsed = 0; - do { - rc = sdmmcSendCmd(drv); - - if (rc == SDMMC_OK && !(ocr & SD_OCR_BUSYN)) - rc = SDMMC_BUSY; - - } - while (rc == SDMMC_BUSY && !drv->timeout_elapsed); - - if (rc != SDMMC_OK) - return rc; - - /* Analyze the final contents of the OCR Register */ -#if 0 - TRACE("Device supports%s%s 3.0V:[%c%c%c%c%c%c]" - " 3.3V:[%c%c%c%c%c%c]\n\r", - ocr & MMC_OCR_VDD_170_195 ? " 1.8V" : "", - ocr & MMC_OCR_VDD_200_270 ? " 2.xV" : "", - ocr & SD_OCR_VDD_27_28 ? 'X' : '.', - ocr & SD_OCR_VDD_28_29 ? 'X' : '.', - ocr & SD_OCR_VDD_29_30 ? 'X' : '.', - ocr & SD_OCR_VDD_30_31 ? 'X' : '.', - ocr & SD_OCR_VDD_31_32 ? 'X' : '.', - ocr & SD_OCR_VDD_32_33 ? 'X' : '.', - ocr & SD_OCR_VDD_30_31 ? 'X' : '.', - ocr & SD_OCR_VDD_31_32 ? 'X' : '.', - ocr & SD_OCR_VDD_32_33 ? 'X' : '.', - ocr & SD_OCR_VDD_33_34 ? 'X' : '.', - ocr & SD_OCR_VDD_34_35 ? 'X' : '.', - ocr & SD_OCR_VDD_35_36 ? 'X' : '.'); -#endif - TRACE_INFO_1("Device access 0x%lx\n\r", ocr >> 29 & 0x3ul); - - *hc = (ocr & MMC_OCR_ACCESS_MODE) == MMC_OCR_ACCESS_SECTOR? true : false; - - return SDMMC_OK; -} -#endif - -/** - * Asks any card to send the CID numbers - * on the CMD line (any card that is - * connected to the host will respond) - * Returns the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - */ -uint8_t Cmd2(SdmmcDriver *drv) -{ - //sSdmmcCommand *pCmd = &pSd->sdCmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(2) | SDMMC_CMD_bmOD; - drv->cmd.bCmd = 2; - drv->cmd.pResp = drv->card.CID; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - - return bRc; -} - -/** - * Switches the mode of operation of the selected card. - * CMD6 is valid under the "trans" state. - * \return The command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pSwitchArg Pointer to the SWITCH_FUNC command argument. - * \param pStatus Pointer to where the 512bit status is returned. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param pResp Pointer to where the response is returned. - */ -uint8_t SdCmd6(SdmmcDriver *drv, const SdCmd6Arg * pSwitchArg, uint8_t * pStatus, uint32_t * pResp) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - //assert(pSd); - //assert(pSwitchArg); - - _ResetCmd(&drv->cmd); - - pCmd->bCmd = 6; - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - - pCmd->dwArg = (pSwitchArg->set << 31) - | (pSwitchArg->reserved << 30) - | (pSwitchArg->func_grp6 << 20) - | (pSwitchArg->func_grp5 << 16) - | (pSwitchArg->pwr_limit << 12) - | (pSwitchArg->drv_strgth << 8) - | (pSwitchArg->cmd_sys << 4) - | (pSwitchArg->acc_mode << 0); - - if (pStatus) { - pCmd->wBlockSize = 512 / 8; - pCmd->wNbBlocks = 1; - pCmd->pData = pStatus; - } - pCmd->pResp = pResp; - drv->timeout_elapsed = -1; - bRc = sdmmcSendCmd(drv); - return bRc; -} - -/** - * Ask the SD card to publish a new relative address (RCA) - * or - * Assign relative address to the MMC card - * Returns the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pRsp Pointer to buffer to fill response (address on 31:16). - */ -/** - * Sends SD Memory Card interface condition, which includes host supply - * voltage information and asks the card whether card supports voltage. - * Should be performed at initialization time to detect the card type. - * \param pSd Pointer to a SD card driver instance. - * \param supplyVoltage Expected supply voltage(SD). - * \return 0 if successful; - * otherwise returns SD_ERROR_NORESPONSE if the card did not answer - * the command, or SDMMC_ERROR. - */ -uint8_t SdCmd8(SdmmcDriver *drv, uint8_t supplyVoltage) -{ - - const uint32_t arg = (supplyVoltage << SD_IFC_VHS_Pos) | SD_IFC_CHK_PATTERN_STD; - uint32_t dwResp = 0; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command information */ - drv->cmd.bCmd = 8; - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(7) | SDMMC_CMD_bmOD; - drv->cmd.dwArg = arg; - drv->cmd.pResp = &dwResp; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - - /* Expect the R7 response, which is the card interface condition. - * Expect VCA to match VHS, and the check pattern to match as well. */ - if (bRc == SDMMC_OK && (dwResp & (SD_IFC_VHS_Msk | SD_IFC_CHK_PATTERN_Msk)) == arg) - return SDMMC_OK; - else if (bRc == SDMMC_NO_RESPONSE) - return SDMMC_NO_RESPONSE; - else - return SDMMC_ERR; -} - -/** - * Command toggles a card between the - * stand-by and transfer states or between - * the programming and disconnect states. - * Returns the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param cardAddr Relative Card Address (0 deselects all). - */ -uint8_t Cmd3(SdmmcDriver *drv) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint32_t dwResp; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.bCmd = 3; - drv->cmd.pResp = &dwResp; - -#ifndef SDMMC_TRIM_MMC - if (drv->card.bCardType == CARD_MMC || drv->card.bCardType == CARD_MMCHD) { - uint16_t wNewAddr = (uint16_t)max_u32(( drv->card.wAddress + 1) & 0xffff, 2); - pCmd->dwArg = wNewAddr << 16; - - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1) | SDMMC_CMD_bmOD; - - drv->timeout_elapsed = -1; - bRc = sdmmcSendCmd(drv); - if (bRc == SDMMC_OK) { - drv->card.wAddress = wNewAddr; - } - } - else -#endif - { - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(6) | SDMMC_CMD_bmOD; - drv->timeout_elapsed = -1; - bRc = sdmmcSendCmd(drv); - - if (bRc == SDMMC_OK) { - drv->card.wAddress = dwResp >> 16; - } - } - return bRc; -} - -uint8_t Cmd7(SdmmcDriver *drv, uint16_t address) -{ - //sSdmmcCommand *pCmd = &pSd->sdCmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - /* If this function is used to transition the MMC device from the - * Disconnected to Programming state, then busy checking is required */ - if (address) - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(1) | SDMMC_CMD_bmBUSY; - else - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(0); - drv->cmd.bCmd = 7; - drv->cmd.dwArg = address << 16; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - -uint8_t Cmd9(SdmmcDriver *drv) -{ - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(2); - drv->cmd.bCmd = 9; - drv->cmd.dwArg = drv->card.wAddress << 16; - drv->cmd.pResp = drv->card.CSD; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - -uint8_t Cmd11(SdmmcDriver *drv, uint32_t * pStatus) -{ - //sSdmmcCommand *pCmd = &pSd->sdCmd; - - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.bCmd = 11; - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(1); - drv->cmd.dwArg = 0; - drv->cmd.pResp = pStatus; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - - return bRc; -} - -/** - * Forces the card to stop transmission - * \param pSd Pointer to a SD card driver instance. - * \param pStatus Pointer to a status variable. - */ -uint8_t Cmd12(SdmmcDriver *drv, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(pCmd); - - /* Fill command */ - pCmd->bCmd = 12; - pCmd->cmdOp.wVal = SDMMC_CMD_CSTOP | SDMMC_CMD_bmBUSY; - pCmd->pResp = pStatus; - - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - - -/** - * Addressed card sends its status register. - * Returns the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pStatus Pointer to a status variable. - */ -uint8_t Cmd13(SdmmcDriver *drv, uint32_t * pStatus) -{ - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.bCmd = 13; - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(1); - drv->cmd.dwArg = drv->card.wAddress << 16; - drv->cmd.pResp = pStatus; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - - -/** - * A host reads the reversed bus testing data pattern from a card - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pData Pointer to the buffer to be filled. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param len Length of data in byte - * \param pStatus Pointer response buffer as status return. - */ -#ifndef SDMMC_TRIM_MMC -uint8_t Cmd14(SdmmcDriver *drv, uint8_t * pData, uint8_t len, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - pCmd->bCmd = 14; - pCmd->pResp = pStatus; - pCmd->wBlockSize = len; - pCmd->wNbBlocks = 1; - pCmd->pData = pData; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - -/** - * Continously transfers datablocks from card to host until interrupted by a - * STOP_TRANSMISSION command. - * \param pSd Pointer to a SD card driver instance. - * \param nbBlocks Number of blocks to send. - * \param pData Pointer to the buffer to be filled. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param address Data Address on SD/MMC card. - * \param pStatus Pointer to the response status. - * \param fCallback Pointer to optional callback invoked on command end. - * NULL: Function return until command finished. - * Pointer: Return immediately and invoke callback at end. - * Callback argument is fixed to a pointer to sSdCard instance. - */ -uint8_t Cmd18(SdmmcDriver *drv, - uint16_t * nbBlock, - uint8_t * pData, - uint32_t address, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(pCmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - pCmd->bCmd = 18; - pCmd->dwArg = address; - pCmd->pResp = pStatus; - pCmd->wBlockSize = drv->card.wCurrBlockLen; - pCmd->wNbBlocks = *nbBlock; - pCmd->pData = pData; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - if (bRc == SDMMC_CHANGED) - *nbBlock = pCmd->wNbBlocks; - return bRc; -} - -/** - * A host sends the bus test data pattern to a card. - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pData Pointer to the buffer to be filled. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param len Length of data in byte - * \param pStatus Pointer response buffer as status return. -*/ - uint8_t Cmd19(SdmmcDriver *drv, uint8_t * pData, uint8_t len, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CDATATX(1); - pCmd->bCmd = 19; - pCmd->pResp = pStatus; - pCmd->wBlockSize = len; - pCmd->wNbBlocks = 1; - pCmd->pData = pData; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} -#endif - -uint8_t Cmd16(SdmmcDriver *drv, uint16_t blkLen) -{ - //sSdmmcCommand *pCmd = &pSd->sdCmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - drv->cmd.cmdOp.wVal = SDMMC_CMD_CNODATA(1); - drv->cmd.bCmd = 16; - drv->cmd.dwArg = blkLen; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - - return bRc; -} - - -/** - * Read single block command - * \param pSd Pointer to a SD card driver instance. - * \param pData Pointer to the buffer to be filled. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param address Data Address on SD/MMC card. - * \param pStatus Pointer response buffer as status return. - * \param fCallback Pointer to optional callback invoked on command end. - * NULL: Function return until command finished. - * Pointer: Return immediately and invoke callback at end. - * Callback argument is fixed to a pointer to sSdCard instance. - */ -uint8_t Cmd17(SdmmcDriver *drv, - uint8_t * pData, - uint32_t address, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(pCmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - pCmd->bCmd = 17; - pCmd->dwArg = address; - pCmd->pResp = pStatus; - pCmd->wBlockSize =drv->card.wCurrBlockLen; - pCmd->wNbBlocks = 1; - pCmd->pData = pData; - - - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - - -/** - * Defines the number of blocks (read/write) and the reliable writer parameter - * (write) for a block read or write command - * data (CSD) on the CMD line. - * Returns the command transfer result (see SendMciCommand). - * \param pSd Pointer to a SD card driver instance. - * \param write Write Request parameter. - * \param blocks number of blocks. - */ -uint8_t Cmd23(SdmmcDriver *drv, uint8_t write, uint32_t blocks, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(pCmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1); - pCmd->bCmd = 23; - pCmd->wNbBlocks = 0; - pCmd->dwArg = write << 31 | blocks; - pCmd->pResp = pStatus; - - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - -/** - * Write single block command - * \param pSd Pointer to a SD card driver instance. - * \param blockSize Block size (shall be set to 512 in case of high capacity). - * \param pData Pointer to the buffer to be filled. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param address Data Address on SD/MMC card. - * \param pStatus Pointer to response buffer as status. - * \param fCallback Pointer to optional callback invoked on command end. - * NULL: Function return until command finished. - * Pointer: Return immediately and invoke callback at end. - * Callback argument is fixed to a pointer to sSdCard instance. - */ -uint8_t Cmd24(SdmmcDriver *drv, - uint8_t * pData, - uint32_t address, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(pCmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CDATATX(1); - pCmd->bCmd = 24; - pCmd->dwArg = address; - pCmd->pResp = pStatus; - pCmd->wBlockSize =drv->card.wCurrBlockLen; - pCmd->wNbBlocks = 1; - pCmd->pData = pData; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - -/** - * Write multiple block command - * \param pSd Pointer to a SD card driver instance. - * \param blockSize Block size (shall be set to 512 in case of high capacity). - * \param nbBlock Number of blocks to send. - * \param pData Pointer to the buffer to be filled. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param address Data Address on SD/MMC card. - * \param pStatus Pointer to the response buffer as status. - * \param fCallback Pointer to optional callback invoked on command end. - * NULL: Function return until command finished. - * Pointer: Return immediately and invoke callback at end. - * Callback argument is fixed to a pointer to sSdCard instance. - */ -uint8_t Cmd25(SdmmcDriver *drv, - uint16_t * nbBlock, - uint8_t * pData, - uint32_t address, uint32_t * pStatus) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(pCmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CDATATX(1); - pCmd->bCmd = 25; - pCmd->dwArg = address; - pCmd->pResp = pStatus; - pCmd->wBlockSize =drv->card.wCurrBlockLen; - pCmd->wNbBlocks = *nbBlock; - pCmd->pData = pData; - - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - if (bRc == SDMMC_CHANGED) - *nbBlock = pCmd->wNbBlocks; - return bRc; -} - - -/** - * SDIO IO_RW_DIRECT command, response R5. - * \return the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pIoData Pointer to input argument (\ref SdioRwDirectArg) and - * response (\ref SdmmcR5) buffer. - * \param fCallback Pointer to optional callback invoked on command end. - * NULL: Function return until command finished. - * Pointer: Return immediately and invoke callback at end. - * Callback argument is fixed to a pointer to sSdCard instance. - */ -uint8_t Cmd52(SdmmcDriver *drv, - uint8_t wrFlag, - uint8_t funcNb, uint8_t rdAfterWr, uint32_t addr, uint32_t * pIoData) -{ - SdioCmd52Arg *pArg52 = (SdioCmd52Arg *) pIoData; - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - pArg52->rwFlag = wrFlag; - pArg52->functionNum = funcNb; - pArg52->rawFlag = rdAfterWr; - pArg52->regAddress = addr; - - _ResetCmd(&drv->cmd); - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(5) | SDMMC_CMD_bmIO; - pCmd->bCmd = 52; - pCmd->dwArg = *pIoData; - pCmd->pResp = pIoData; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} -/** - * Indicates to the card that the next command is an application specific - * command rather than a standard command. - * \return the command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param cardAddr Card Relative Address. - */ -uint8_t Cmd55(SdmmcDriver *drv, uint16_t cardAddr) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint32_t dwResp; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command information */ - pCmd->bCmd = 55; - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1)| (cardAddr ? 0 : SDMMC_CMD_bmOD); - pCmd->dwArg = cardAddr << 16; - pCmd->pResp = &dwResp; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} - - -/** - * Defines the data bus width (00=1bit or 10=4 bits bus) to be used for data - * transfer. - * The allowed data bus widths are given in SCR register. - * \param drv Pointer to \ref SdmmcDriver instance. - * \param busWidth Bus width in bits (4 or 1). - * \return the command transfer result (see SendCommand). - */ -uint8_t Acmd6(SdmmcDriver *drv, uint8_t busWidth) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t error; - - TRACE_INFO_1("Acmd%u\n\r", 6); - - error = Cmd55(drv, drv->card.wAddress); - - if (!error) { - _ResetCmd(&drv->cmd); - - pCmd->bCmd = 6; - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1); - pCmd->dwArg = (busWidth == 4) ? SD_SSR_DATA_BUS_WIDTH_4BIT : SD_SSR_DATA_BUS_WIDTH_1BIT; - drv->timeout_elapsed = -1; - error = sdmmcSendCmd(drv); - } - else { - if (error) { - TRACE_ERROR_2("Acmd%u %s\n\r", 6, SD_StringifyRetCode(error)); - } - } - return error; -} - - -/** - * From the selected card get its SD Status Register (SSR). - * ACMD13 is valid under the Transfer state. - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pSSR Pointer to a 64-byte buffer receiving the contents of the SSR. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param pResp Pointer to where the response is returned. - * \return The command transfer result (see SendCommand). - */ -uint8_t Acmd13(SdmmcDriver *drv, uint8_t * pSSR, uint32_t * pResp) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t error; - - //assert(pSd); - - TRACE_INFO_1("Acmd%u\n\r", 13); - - error = Cmd55(drv, drv->card.wAddress); - - if (!error) { - - _ResetCmd(&drv->cmd); - - pCmd->bCmd = 13; - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - if (pSSR) { - pCmd->wBlockSize = 512 / 8; - pCmd->wNbBlocks = 1; - pCmd->pData = pSSR; - } - pCmd->pResp = pResp; - drv->timeout_elapsed = -1; - error = sdmmcSendCmd(drv); - - } else { - if (error) { - TRACE_ERROR_2("Acmd%u %s\n\r", 13, SD_StringifyRetCode(error)); - } - } - return error; -} - -/** - * Asks to all cards to send their operations conditions. - * Returns the command transfer result (see SendCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param low_sig_lvl In: tells whether the host supports UHS-I timing modes. - * Out: tells whether the device may switch to low signaling level. - * \param hc In: tells whether the device has replied to SEND_IF_COND. - * Out: tells whether the device is a high capacity device. - */ -uint8_t Acmd41(SdmmcDriver *drv, bool * low_sig_lvl, bool * hc) -{ - - sSdmmcCommand *pCmd = &drv->cmd; - /* TODO get this board-specific value from platform code. On the - * SAMA5D2-XULT board, VDD is 3.3V ± 1%. */ - const uint32_t vdd_range = SD_OCR_VDD_32_33 | SD_OCR_VDD_33_34; - uint32_t arg, ocr = 0; - uint8_t rc; - //int8_t elapsed = -1; - - //trace_debug("Acmd%u\n\r", 41); - /* Provided the device has answered the SEND_IF_COND command, raise the - * Host Capacity Support flag. Also, set the SDXC Power Control flag. - * TODO assign XPC depending on board capabilities. */ - arg = *hc ? SD_OPC_HCS | SD_OPC_XPC : 0; - /* Preparing UHS-I timing modes, ask the device whether it's in a - * position to switch to low signaling voltage. */ - arg |= *low_sig_lvl ? SD_OPC_S18R : 0; - /* Tell the SD device which voltage the host supplies to the VDD line */ - arg |= vdd_range; - - - drv->timeout_ticks = TIME_S2I(1); - drv->timeout_elapsed = 0; - - do { - rc = Cmd55(drv, 0); - - if (rc != SDMMC_OK) - break; - - _ResetCmd(&drv->cmd); - - pCmd->bCmd = 41; - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(3); - pCmd->dwArg = arg; - pCmd->pResp = &ocr; - drv->timeout_elapsed = -1; - rc = sdmmcSendCmd(drv); - - if (rc != SDMMC_OK) - break; - - - } while (!(ocr & SD_OCR_BUSYN) && !drv->timeout_elapsed); - - if (!(ocr & SD_OCR_BUSYN) && rc == SDMMC_OK) - /* Supply voltage range is incompatible */ - rc = SDMMC_BUSY; - if (rc != SDMMC_OK) { - TRACE_ERROR_2("Acmd%u %s\n\r", 41, SD_StringifyRetCode(rc)); - } - else { -#if 0 - /* Analyze the final contents of the OCR Register */ - trace_info("Device supports%s%s 3.0V:[%c%c%c%c%c%c]" - " 3.3V:[%c%c%c%c%c%c]\n\r", - ocr & SD_OCR_VDD_LOW ? " 1.xV" : "", "", - ocr & SD_OCR_VDD_27_28 ? 'X' : '.', - ocr & SD_OCR_VDD_28_29 ? 'X' : '.', - ocr & SD_OCR_VDD_29_30 ? 'X' : '.', - ocr & SD_OCR_VDD_30_31 ? 'X' : '.', - ocr & SD_OCR_VDD_31_32 ? 'X' : '.', - ocr & SD_OCR_VDD_32_33 ? 'X' : '.', - ocr & SD_OCR_VDD_30_31 ? 'X' : '.', - ocr & SD_OCR_VDD_31_32 ? 'X' : '.', - ocr & SD_OCR_VDD_32_33 ? 'X' : '.', - ocr & SD_OCR_VDD_33_34 ? 'X' : '.', - ocr & SD_OCR_VDD_34_35 ? 'X' : '.', - ocr & SD_OCR_VDD_35_36 ? 'X' : '.'); -#endif - /* Verify that arg[23:15] range fits within OCR[23:15] range */ - if ((ocr & vdd_range) != vdd_range) - rc = SDMMC_NOT_SUPPORTED; - if (*low_sig_lvl) - *low_sig_lvl = ocr & SD_OCR_S18A ? true : false; - *hc = ocr & SD_OCR_CCS ? true : false; - } - return rc; - -} - - -/** - * From the selected card get its SD CARD Configuration Register (SCR). - * ACMD51 is valid under the Transfer state. - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pSCR Pointer to an 8-byte buffer receiving the contents of the SCR. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \param pResp Pointer to where the response is returned. - * \return The command transfer result (see SendCommand). - */ -uint8_t Acmd51(SdmmcDriver *drv, uint8_t * pSCR, uint32_t * pResp) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t error; - - - TRACE_INFO_1("Acmd%u\n\r", 51); - - error = Cmd55(drv, drv->card.wAddress); - - if (!error) { - - _ResetCmd(pCmd); - - pCmd->bCmd = 51; - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - - if (pSCR) { - pCmd->wBlockSize = 64 / 8; - pCmd->wNbBlocks = 1; - pCmd->pData = pSCR; - } - pCmd->pResp = pResp; - drv->timeout_elapsed = -1; - error = sdmmcSendCmd(drv); - - } else { - if (error) { - TRACE_ERROR_2("Acmd%u %s\n\r", 51, SD_StringifyRetCode(error)); - } - } - return error; -} - -/** - * SEND_EXT_CSD, to get EXT_CSD register as a block of data. - * Valid under "trans" state. - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pEXT 512 byte buffer pointer for EXT_CSD data. - * The buffer shall follow the peripheral and DMA alignment requirements. - * \return 0 if successful; - * otherwise returns SD_ERROR_NORESPONSE if the card did not answer - * the command, or SDMMC_ERROR. - */ -#ifndef SDMMC_TRIM_MMC - -/** - * Switches the mode of operation of the selected card or - * Modifies the EXT_CSD registers. - * CMD6 is valid under the "trans" state. - * \return The command transfer result (see SendMciCommand). - * \param pSd Pointer to a SD/MMC card driver instance. - * \param pSwitchArg Pointer to a MmcCmd6Arg instance. - * \param pResp Pointer to where the response is returned. - */ -uint8_t MmcCmd6(SdmmcDriver *drv, const void *pSwitchArg, uint32_t * pResp) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - MmcCmd6Arg *pMmcSwitch; - - //assert(pSd); -// assert(pSwitchArg); - - _ResetCmd(&drv->cmd); - - pMmcSwitch = (MmcCmd6Arg *) pSwitchArg; - pCmd->bCmd = 6; - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1) | SDMMC_CMD_bmBUSY; - pCmd->dwArg = (pMmcSwitch->access << 24) - | (pMmcSwitch->index << 16) - | (pMmcSwitch->value << 8) - | (pMmcSwitch->cmdSet << 0); - pCmd->pResp = pResp; - drv->timeout_elapsed = -1; - bRc = sdmmcSendCmd(drv); - - if (!bRc && pResp && *pResp & STATUS_MMC_SWITCH) { - TRACE_INFO_1("st %lx\n\r", *pResp); - } - return bRc; -} - -uint8_t MmcCmd8(SdmmcDriver *drv) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - pCmd->bCmd = 8; - pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1); - pCmd->wBlockSize = 512; - pCmd->wNbBlocks = 1; - pCmd->pData = drv->card.EXT; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - - return bRc; -} -#endif - -/** - * SDIO SEND OPERATION CONDITION (OCR) command. - * Sends host capacity support information and acrivates the card's - * initialization process. - * \return The command transfer result (see SendMciCommand). - * \param drv Pointer to \ref SdmmcDriver instance. - * \param pIo Pointer to data sent as well as response buffer (32bit). - */ -#ifndef SDMMC_TRIM_SDIO -uint8_t Cmd5(SdmmcDriver *drv, uint32_t * pIo) -{ - sSdmmcCommand *pCmd = &drv->cmd; - uint8_t bRc; - - _ResetCmd(&drv->cmd); - - /* Fill command */ - pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(4) | SDMMC_CMD_bmIO - | SDMMC_CMD_bmOD; - pCmd->bCmd = 5; - pCmd->dwArg = *pIo; - pCmd->pResp = pIo; - drv->timeout_elapsed = -1; - /* Send command */ - bRc = sdmmcSendCmd(drv); - return bRc; -} -#endif - - -uint8_t CancelCommand(SdmmcDriver *driver) -{ - //assert(set); - osalDbgCheck(driver->state != MCID_OFF); - - Sdmmc *regs = driver->regs; - sSdmmcCommand *cmd = &driver->cmd; - uint32_t response; /* The R1 response is 32-bit long */ - uint32_t usec, rc; - - cmd->pResp = &response; - cmd->cmdOp.wVal = SDMMC_CMD_CSTOP | SDMMC_CMD_bmBUSY; - cmd->bCmd = 12; - - if (driver->state != MCID_CMD && driver->state != MCID_ERROR) - return SDMMC_STATE; - //trace_debug("Requested to cancel CMD%u\n\r", set->cmd ? set->cmd->bCmd : 99); - if (driver->state == MCID_ERROR) { - driver->state = MCID_LOCKED; - return SDMMC_OK; - } - //assert(cmd); - /* Asynchronous Abort, if a data transfer has been started */ - if (cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX - || cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_RX) { - /* May the CMD line still be busy, reset it */ - if (regs->SDMMC_PSR & SDMMC_PSR_CMDINHC) { - regs->SDMMC_SRR |= SDMMC_SRR_SWRSTCMD; - while (regs->SDMMC_SRR & SDMMC_SRR_SWRSTCMD) ; - } - /* Issue the STOP_TRANSMISSION command. */ - driver->state = MCID_LOCKED; - driver->resp_len = 0; - driver->blk_index = 0; - driver->cmd_line_released = false; - driver->dat_lines_released = false; - driver->expect_auto_end = false; - - rc = sdmmc_device_command(driver); - - if (rc == SDMMC_OK) { - for (usec = 0; driver->state == MCID_CMD && usec < 500000; usec+= 10) { - - t_usleep(driver,10); - - if (driver->use_polling) { - sdmmc_device_poll(driver); - } - } - } - } - /* Reset CMD and DATn lines */ - regs->SDMMC_SRR |= SDMMC_SRR_SWRSTDAT | SDMMC_SRR_SWRSTCMD; - while (regs->SDMMC_SRR & (SDMMC_SRR_SWRSTDAT | SDMMC_SRR_SWRSTCMD)) ; - - /* Release command */ - cmd->bStatus = SDMMC_USER_CANCEL; - - driver->state = MCID_LOCKED; - - driver->resp_len = 0; - driver->blk_index = 0; - driver->cmd_line_released = false; - driver->dat_lines_released = false; - driver->expect_auto_end = false; - - return SDMMC_OK; -} - - -uint8_t tuneSampling(SdmmcDriver *driver) -{ - //osalDbgCheck(set); - osalDbgCheck(driver->state != MCID_OFF && driver->state != MCID_CMD); - - Sdmmc *regs = driver->regs; - uint32_t response; /* The R1 response is 32-bit long */ - - //test command - driver->cmd.pData = (uint8_t *)&response; - driver->cmd.wBlockSize = 128; - driver->cmd.wNbBlocks = 1; - driver->cmd.pResp = &response; - driver->cmd.dwArg = 0; - driver->cmd.cmdOp.wVal = SDMMC_CMD_CDATARX(1); - driver->cmd.bCmd = 21; - uint16_t hc2r; - uint8_t rc = SDMMC_OK, ix; - - if (driver->tim_mode != SDMMC_TIM_MMC_HS200) - driver->cmd.bCmd = 19; - ix = sdmmc_get_bus_width(driver); - if (ix == 4) - driver->cmd.wBlockSize = 64; - else if (ix != 8) - return SDMMC_PARAM; - /* Start the tuning procedure */ - regs->SDMMC_HC2R |= SDMMC_HC2R_EXTUN; - hc2r = regs->SDMMC_HC2R; - for (ix = 0; hc2r & SDMMC_HC2R_EXTUN && ix < 40; ix++) { - /* Issue the SEND_TUNING_BLOCK command */ - driver->state = MCID_LOCKED; - driver->resp_len = 0; - driver->blk_index = 0; - driver->cmd_line_released = false; - driver->dat_lines_released = false; - driver->expect_auto_end = false; - rc = sdmmc_device_command(driver); - - if (rc != SDMMC_OK) - break; - - /* While tuning the position of the sampling point, usual - * interrupts do not occur. Expect NISTR:BRDRDY only. */ - while (!(regs->SDMMC_NISTR & SDMMC_NISTR_BRDRDY)) ; - regs->SDMMC_NISTR = SDMMC_NISTR_BRDRDY; - //driver->cmd = NULL; - hc2r = regs->SDMMC_HC2R; - } - if (hc2r & SDMMC_HC2R_EXTUN) { - /* Abort the tuning procedure */ - regs->SDMMC_HC2R = hc2r & ~SDMMC_HC2R_EXTUN; - /* Reset the tuning circuit. Use the fixed clock when sampling - * data. */ - regs->SDMMC_HC2R = hc2r & ~SDMMC_HC2R_SCLKSEL - & ~SDMMC_HC2R_EXTUN; - rc = SDMMC_ERR; - } - else if (!(hc2r & SDMMC_HC2R_SCLKSEL)) - rc = SDMMC_ERR; - /* Clear residual interrupts, if any */ - if (regs->SDMMC_NISTR & SDMMC_NISTR_ERRINT) - regs->SDMMC_EISTR = regs->SDMMC_EISTR; - regs->SDMMC_NISTR = regs->SDMMC_NISTR; - driver->state = MCID_LOCKED; - driver->resp_len = 0; - driver->blk_index = 0; - driver->cmd_line_released = false; - driver->dat_lines_released = false; - driver->expect_auto_end = false; - //trace_debug("%u tuning blocks. %s.\n\r", ix, SD_StringifyRetCode(rc)); - return rc; -} - -static void _ResetCmd(sSdmmcCommand * pCmd) -{ - memset(pCmd, 0, sizeof (sSdmmcCommand)); -} - -#endif diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.h deleted file mode 100644 index 6de912fe8..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.h +++ /dev/null @@ -1,273 +0,0 @@ - -#ifndef CH_SDMMC_CMDS_H_ -#define CH_SDMMC_CMDS_H_ - - -/** - * \struct SdCmd6Arg - * Argument for SD CMD6 - */ -typedef struct _SdCmd6Arg { - uint32_t acc_mode:4, /**< [ 3: 0] function group 1, access mode */ - cmd_sys:4, /**< [ 7: 4] function group 2, command system */ - drv_strgth:4, /**< [11: 8] function group 3, driver strength */ - pwr_limit:4, /**< [15:12] function group 4, power limit */ - func_grp5:4, /**< [19:16] function group 5, 0xF or 0x0 */ - func_grp6:4, /**< [23:20] function group 6, 0xF or 0x0 */ - reserved:7, /**< [30:24] reserved 0 */ - set:1; /**< [31 ] operation: 0 to check or 1 to set */ -} SdCmd6Arg, SdSwitchArg; - - - -/** \addtogroup sdmmc_struct_cmdarg SD/MMC command arguments - * Here lists the command arguments for SD/MMC. - * - CMD6 Argument - * - \ref MmcCmd6Arg "MMC CMD6" - * - \ref SdCmd6Arg "SD CMD6" - * - \ref SdioCmd52Arg CMD52 - * - \ref SdioCmd53Arg CMD53 - * @{*/ -/** - * \struct MmcCmd6Arg - * Argument for MMC CMD6 - */ -typedef struct _MmcCmd6Arg { - uint8_t access; - uint8_t index; - uint8_t value; - uint8_t cmdSet; -} MmcCmd6Arg, MmcSwitchArg; -/** - * \struct SdioCmd52Arg - * Argument for SDIO CMD52 - */ -typedef struct _SdioCmd52Arg { - uint32_t data:8, /**< [ 7: 0] data for writing */ - stuff0:1, /**< [ 8] reserved */ - regAddress:17, /**< [25: 9] register address */ - stuff1:1, /**< [ 26] reserved */ - rawFlag:1, /**< [ 27] Read after Write flag */ - functionNum:3, /**< [30:28] Number of the function */ - rwFlag:1; /**< [ 31] Direction, 1:write, 0:read. */ -} SdioCmd52Arg, SdioRwDirectArg; - -#define SDMMC_CMD_bmPOWERON (0x1 ) /**< Do Power ON sequence */ -#define SDMMC_CMD_bmCOMMAND (0x1 << 1) /**< Send command */ -#define SDMMC_CMD_bmDATAMASK (0x3 << 2) /**< Data operation mask */ -#define SDMMC_CMD_bmNODATA (0x0 << 2) /**< No data transfer */ -#define SDMMC_CMD_RX 0x1 /**< data RX */ -#define SDMMC_CMD_bmDATARX (0x1 << 2) /**< Bits for data RX */ -#define SDMMC_CMD_TX 0x2 /**< data TX */ -#define SDMMC_CMD_bmDATATX (0x2 << 2) /**< Bits for data TX */ -#define SDMMC_CMD_STOPXFR 0x3 /**< data stop */ -#define SDMMC_CMD_bmSTOPXFR (0x3 << 2) /**< Bits for transfer stop */ -#define SDMMC_CMD_bmRESPMASK (0x7 << 4) /**< Bits masks response option */ -#define SDMMC_CMD_bmRESP(R) (((R)&0x7) << 4) /**< Bits setup response type: 1 for R1, 2 for R2, ... 7 for R7 */ - - - -/** \addtogroup sdmmc_status_bm SD/MMC Status register constants - * @{*/ -#define STATUS_APP_CMD (1UL << 5) -#define STATUS_SWITCH_ERROR (1UL << 7) -#define STATUS_READY_FOR_DATA (1UL << 8) -#define STATUS_IDLE (0UL << 9) -#define STATUS_READY (1UL << 9) -#define STATUS_IDENT (2UL << 9) -#define STATUS_STBY (3UL << 9) -#define STATUS_TRAN (4UL << 9) -#define STATUS_DATA (5UL << 9) -#define STATUS_RCV (6UL << 9) -#define STATUS_PRG (7UL << 9) -#define STATUS_DIS (8UL << 9) -#define STATUS_BTST (9UL << 9) -#define STATUS_SLEEP (10UL << 9) -#define STATUS_STATE (0xFUL << 9) -#define STATUS_ERASE_RESET (1UL << 13) -#define STATUS_WP_ERASE_SKIP (1UL << 15) -#define STATUS_CIDCSD_OVERWRITE (1UL << 16) -#define STATUS_OVERRUN (1UL << 17) -#define STATUS_UNERRUN (1UL << 18) -#define STATUS_ERROR (1UL << 19) -#define STATUS_CC_ERROR (1UL << 20) -#define STATUS_CARD_ECC_FAILED (1UL << 21) -#define STATUS_ILLEGAL_COMMAND (1UL << 22) -#define STATUS_COM_CRC_ERROR (1UL << 23) -#define STATUS_UN_LOCK_FAILED (1UL << 24) -#define STATUS_CARD_IS_LOCKED (1UL << 25) -#define STATUS_WP_VIOLATION (1UL << 26) -#define STATUS_ERASE_PARAM (1UL << 27) -#define STATUS_ERASE_SEQ_ERROR (1UL << 28) -#define STATUS_BLOCK_LEN_ERROR (1UL << 29) -#define STATUS_ADDRESS_MISALIGN (1UL << 30) -#define STATUS_ADDR_OUT_OR_RANGE (1UL << 31) - -#define STATUS_STOP ((uint32_t)( STATUS_CARD_IS_LOCKED \ - | STATUS_COM_CRC_ERROR \ - | STATUS_ILLEGAL_COMMAND \ - | STATUS_CC_ERROR \ - | STATUS_ERROR \ - | STATUS_STATE \ - | STATUS_READY_FOR_DATA )) - -#define STATUS_WRITE ((uint32_t)( STATUS_ADDR_OUT_OR_RANGE \ - | STATUS_ADDRESS_MISALIGN \ - | STATUS_BLOCK_LEN_ERROR \ - | STATUS_WP_VIOLATION \ - | STATUS_CARD_IS_LOCKED \ - | STATUS_COM_CRC_ERROR \ - | STATUS_ILLEGAL_COMMAND \ - | STATUS_CC_ERROR \ - | STATUS_ERROR \ - | STATUS_ERASE_RESET \ - | STATUS_STATE \ - | STATUS_READY_FOR_DATA )) - -#define STATUS_READ ((uint32_t)( STATUS_ADDR_OUT_OR_RANGE \ - | STATUS_ADDRESS_MISALIGN \ - | STATUS_BLOCK_LEN_ERROR \ - | STATUS_CARD_IS_LOCKED \ - | STATUS_COM_CRC_ERROR \ - | STATUS_ILLEGAL_COMMAND \ - | STATUS_CARD_ECC_FAILED \ - | STATUS_CC_ERROR \ - | STATUS_ERROR \ - | STATUS_ERASE_RESET \ - | STATUS_STATE \ - | STATUS_READY_FOR_DATA )) - -#define STATUS_SD_SWITCH ((uint32_t)( STATUS_ADDR_OUT_OR_RANGE \ - | STATUS_CARD_IS_LOCKED \ - | STATUS_COM_CRC_ERROR \ - | STATUS_ILLEGAL_COMMAND \ - | STATUS_CARD_ECC_FAILED \ - | STATUS_CC_ERROR \ - | STATUS_ERROR \ - | STATUS_UNERRUN \ - | STATUS_OVERRUN \ - /*| STATUS_STATE*/)) - -#define STATUS_MMC_SWITCH ((uint32_t)( STATUS_CARD_IS_LOCKED \ - | STATUS_COM_CRC_ERROR \ - | STATUS_ILLEGAL_COMMAND \ - | STATUS_CC_ERROR \ - | STATUS_ERROR \ - | STATUS_ERASE_RESET \ - /*| STATUS_STATE*/ \ - /*| STATUS_READY_FOR_DATA*/ \ - | STATUS_SWITCH_ERROR )) - -#define SD_OCR_S18A (1ul << 24) /**< Switching to 1.8V signaling level Accepted */ -#define SDIO_OCR_MP (0x1ul << 27) /**< SDIO: Memory present */ -#define SDIO_OCR_NF (0x3ul << 28) /**< SDIO: Number of functions */ -#define MMC_OCR_ACCESS_MODE (0x3ul << 29) /**< MMC: Access mode, 0x2 is sector mode */ -#define MMC_OCR_ACCESS_BYTE (0x0 << 29) /**< MMC: Byte access mode */ -#define MMC_OCR_ACCESS_SECTOR (0x2ul << 29) /**< MMC: Sector access mode */ -#define SD_OCR_UHS_II (1ul << 29) /**< SD: UHS-II Card Status */ -#define SD_OCR_CCS (1ul << 30) /**< SD: Card Capacity Status */ -#define SD_OCR_BUSYN (1ul << 31) /**< SD/MMC: Busy Status */ - - -/** \addtogroup sdmmc_sd_status SD/MMC status fields - * @{ - */ -/** SSR (SD Status) access macros (512 bits, 16 * 32 bits, 64 * 8 bits). */ -#define SD_ST(pSt, field, bits) SD_GetField(pSt, 512, field, bits) -#define SD_SSR_DAT_BUS_WIDTH(pSt) (uint8_t)SD_ST(pSt, 510, 2) /**< Bus width, 00: default, 10:4-bit */ -#define SD_SSR_DATA_BUS_WIDTH_1BIT 0x0 /**< 1-bit bus width */ -#define SD_SSR_DATA_BUS_WIDTH_4BIT 0x2 /**< 4-bit bus width */ -#define SD_SSR_SECURED_MODE(pSt) (uint8_t)SD_ST(pSt, 509, 1) /**< Secured Mode */ -#define SD_SSR_CARD_TYPE(pSt) (uint16_t)SD_ST(pSt, 480, 16) -#define SD_SSR_CARD_TYPE_RW 0x0000 /**< Regular SD R/W Card */ -#define SD_SSR_CARD_TYPE_ROM 0x0001 /**< SD ROM Card */ -#define SD_SSR_CARD_TYPE_OTP 0x0002 /**< OTP SD Card */ -#define SD_SSR_SIZE_OF_PROTECTED_AREA(pSt) SD_ST(pSt, 448, 32) /**< STD: ThisSize*Multi*BlockLen, HC: Size in bytes */ -#define SD_SSR_SPEED_CLASS(pSt) (uint8_t)SD_ST(pSt, 440, 8) /**< Speed Class, value can be calculated by Pw/2 */ -#define SD_SSR_SPEED_CLASS_0 0 -#define SD_SSR_SPEED_CLASS_2 1 // >= 2MB/s -#define SD_SSR_SPEED_CLASS_4 2 // >= 4MB/s -#define SD_SSR_SPEED_CLASS_6 3 // >= 6MB/s -#define SD_SSR_SPEED_CLASS_10 4 // >= 10MB/s -#define SD_SSR_PERFORMANCE_MOVE(pSt) (uint8_t)SD_ST(pSt, 432, 8) /**< 8-bit, by 1MB/s step. */ -#define SD_SSR_AU_SIZE(pSt) (uint8_t)SD_ST(pSt, 428, 4) /**< AU Size, in power of 2 from 16KB */ -#define SD_SSR_AU_SIZE_16K 1 -#define SD_SSR_AU_SIZE_32K 2 -#define SD_SSR_AU_SIZE_64K 3 -#define SD_SSR_AU_SIZE_128K 4 -#define SD_SSR_AU_SIZE_256K 5 -#define SD_SSR_AU_SIZE_512K 6 -#define SD_SSR_AU_SIZE_1M 7 -#define SD_SSR_AU_SIZE_2M 8 -#define SD_SSR_AU_SIZE_4M 9 -#define SD_SSR_AU_SIZE_8M 0xa -#define SD_SSR_AU_SIZE_12M 0xb -#define SD_SSR_AU_SIZE_16M 0xc -#define SD_SSR_AU_SIZE_24M 0xd -#define SD_SSR_AU_SIZE_32M 0xe -#define SD_SSR_AU_SIZE_64M 0xf -#define SD_SSR_ERASE_SIZE(pSt) (uint16_t)SD_ST(pSt, 408, 16) /**< 16-bit, number of AUs erased. */ -#define SD_SSR_ERASE_TIMEOUT(pSt) (uint8_t)SD_ST(pSt, 402, 6) /**< Timeout value for erasing areas */ -#define SD_SSR_ERASE_OFFSET(pSt) (uint8_t)SD_ST(pSt, 400, 2) /**< Fixed offset value added to erase time */ -#define SD_SSR_UHS_SPEED_GRADE(pSt) (uint8_t)SD_ST(pSt, 396, 4) /**< Speed Grade for UHS mode */ -#define SD_SSR_SPEED_GRADE_0 0x0 -#define SD_SSR_SPEED_GRADE_1 0x1 -#define SD_SSR_SPEED_GRADE_3 0x3 -#define SD_SSR_UHS_AU_SIZE(pSt) (uint8_t)SD_ST(pSt, 392, 4) /**< Size of AU for UHS mode */ -#define SD_SSR_UHS_AU_SIZE_UNDEF 0 -#define SD_SSR_UHS_AU_SIZE_1M 0x7 -#define SD_SSR_UHS_AU_SIZE_2M 0x8 -#define SD_SSR_UHS_AU_SIZE_4M 0x9 -#define SD_SSR_UHS_AU_SIZE_8M 0xa -#define SD_SSR_UHS_AU_SIZE_12M 0xb -#define SD_SSR_UHS_AU_SIZE_16M 0xc -#define SD_SSR_UHS_AU_SIZE_24M 0xd -#define SD_SSR_UHS_AU_SIZE_32M 0xe -#define SD_SSR_UHS_AU_SIZE_64M 0xf - - -extern uint8_t tuneSampling(SdmmcDriver *driver); -extern uint8_t CancelCommand(SdmmcDriver *driver); -extern uint8_t CmdPowerOn(SdmmcDriver *drv); -extern uint8_t SdCmd6(SdmmcDriver *drv, - const SdCmd6Arg * pSwitchArg, uint8_t * pStatus, uint32_t * pResp); -extern uint8_t SdCmd8(SdmmcDriver *drv, uint8_t supplyVoltage); -extern uint8_t Acmd6(SdmmcDriver *pSd, uint8_t busWidth); -extern uint8_t Acmd13(SdmmcDriver *drv, uint8_t * pSSR, uint32_t * pResp); -extern uint8_t Acmd41(SdmmcDriver *drv, bool * low_sig_lvl, bool * hc); -extern uint8_t Acmd51(SdmmcDriver *drv, uint8_t * pSCR, uint32_t * pResp); -extern uint8_t Cmd0(SdmmcDriver *drv, uint8_t arg); -extern uint8_t Cmd1(SdmmcDriver *drv, bool * hc); -extern uint8_t Cmd2(SdmmcDriver *drv); -extern uint8_t Cmd3(SdmmcDriver *drv); -extern uint8_t Cmd5(SdmmcDriver *drv, uint32_t * pIo); -extern uint8_t Cmd7(SdmmcDriver *drv, uint16_t address); -extern uint8_t Cmd9(SdmmcDriver *drv); -extern uint8_t Cmd11(SdmmcDriver *drv, uint32_t * pStatus); -extern uint8_t Cmd12(SdmmcDriver *drv, uint32_t * pStatus); -extern uint8_t Cmd13(SdmmcDriver *drv, uint32_t * pStatus); -extern uint8_t Cmd14(SdmmcDriver *drv, uint8_t * pData, uint8_t len, uint32_t * pStatus); - -extern uint8_t Cmd16(SdmmcDriver *drv, uint16_t blkLen); -extern uint8_t Cmd17(SdmmcDriver *drv, - uint8_t * pData, - uint32_t address, uint32_t * pStatus); -extern uint8_t Cmd18(SdmmcDriver *drv,uint16_t * nbBlock,uint8_t * pData,uint32_t address, uint32_t * pStatus); -extern uint8_t Cmd19(SdmmcDriver *drv, uint8_t * pData, uint8_t len, uint32_t * pStatus); -extern uint8_t Cmd23(SdmmcDriver *drv, uint8_t write, uint32_t blocks, uint32_t * pStatus); -extern uint8_t Cmd24(SdmmcDriver *drv, - uint8_t * pData, - uint32_t address, uint32_t * pStatus); -extern uint8_t Cmd25(SdmmcDriver *drv, - uint16_t * nbBlock, - uint8_t * pData, - uint32_t address, uint32_t * pStatus); -extern uint8_t Cmd52(SdmmcDriver *drv,uint8_t wrFlag,uint8_t funcNb, uint8_t rdAfterWr, uint32_t addr, uint32_t * pIoData); - -extern uint8_t Cmd55(SdmmcDriver *drv, uint16_t cardAddr); - -extern uint8_t MmcCmd8(SdmmcDriver *drv); -extern uint8_t MmcCmd6(SdmmcDriver *drv, const void *pSwitchArg, uint32_t * pResp); - - -#endif /* CH_SDMMC_CMDS_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.c b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.c deleted file mode 100644 index 7bdd136e0..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.c +++ /dev/null @@ -1,1917 +0,0 @@ -#include -#include "hal.h" - -#if (SAMA_USE_SDMMC == TRUE) - -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_cmds.h" -#include "ch_sdmmc_sdio.h" -#include "ch_sdmmc_sd.h" -#include "ch_sdmmc_mmc.h" -/** A software event, never raised by the hardware, specific to this driver */ -#define SDMMC_NISTR_CUSTOM_EVT (0x1u << 13) - -/** Device status */ -#define STAT_ADDRESS_OUT_OF_RANGE (1UL << 31) -#define STAT_ADDRESS_MISALIGN (1UL << 30) -#define STAT_BLOCK_LEN_ERROR (1UL << 29) -#define STAT_ERASE_SEQ_ERROR (1UL << 28) -#define STAT_ERASE_PARAM (1UL << 27) -#define STAT_WP_VIOLATION (1UL << 26) -#define STAT_DEVICE_IS_LOCKED (1UL << 25) -#define STAT_LOCK_UNLOCK_FAILED (1UL << 24) -#define STAT_COM_CRC_ERROR (1UL << 23) -#define STAT_ILLEGAL_COMMAND (1UL << 22) -#define STAT_DEVICE_ECC_FAILED (1UL << 21) -#define STAT_CC_ERROR (1UL << 20) -#define STAT_ERROR (1UL << 19) -#define STAT_CID_OVERWRITE (1UL << 16) -#define STAT_ERASE_SKIP (1UL << 15) -#define STAT_CARD_ECC_DISABLED (1UL << 14) -#define STAT_ERASE_RESET (1UL << 13) -#define STAT_CURRENT_STATE (0xfUL << 9) -#define STAT_READY_FOR_DATA (1UL << 8) -#define STAT_SWITCH_ERROR (1UL << 7) -#define STAT_EXCEPTION_EVENT (1UL << 6) -#define STAT_APP_CMD (1UL << 5) - -union uint32_u { - uint32_t word; - uint8_t bytes[4]; -}; - -static void calibrate_zout(Sdmmc * regs); -void reset_peripheral(SdmmcDriver *driver); -void sdmmc_set_capabilities( - Sdmmc * regs, - uint32_t caps0, uint32_t caps0_mask, - uint32_t caps1, uint32_t caps1_mask); - -static uint8_t HwReset(SdmmcDriver *driver); - - - -static void sdmmc_get_response(SdmmcDriver *driver, sSdmmcCommand *cmd, bool complete, uint32_t *out); - -static uint8_t sdmmc_build_dma_table( SdmmcDriver *driver ); -static uint8_t unplug_device(SdmmcDriver *driver); -static uint8_t sdmmc_set_speed_mode(SdmmcDriver *driver, uint8_t mode,bool verify); -static uint8_t sdmmc_set_bus_width(SdmmcDriver *driver, uint8_t bits); - - -uint8_t sdmmc_device_lowlevelcfg(SdmmcDriver *driver) -{ - uint8_t res; - - - TRACE_INFO_1("Processor clock: %u MHz\r\n", ((unsigned)(SAMA_PCK / 1000000) )); - TRACE_INFO_1("Master clock: %u MHz\r\n", ((unsigned)(SAMA_MCK / 1000000)) ); - - if (driver->config->slot_id == SDMMC_SLOT0) { - driver->regs = SDMMC0; - pmcEnableSDMMC0(); - } else if (driver->config->slot_id == SDMMC_SLOT1) { - driver->regs = SDMMC1; - pmcEnableSDMMC1(); - } - - switch (driver->config->slot_id) { - - case SDMMC_SLOT0: { - - uint32_t caps0 = BOARD_SDMMC0_CAPS0; - - /* Program capabilities for SDMMC0 */ - sdmmc_set_capabilities((Sdmmc*) SDMMC0, caps0, CAPS0_MASK, 0, 0); - -#if 0 - /* Configure SDMMC0 pins */ - - /** SDMMC0 pin Card Detect (CD) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN13), 0U, - PAL_SAMA_FUNC_PERIPH_A | PAL_MODE_INPUT_PULLUP); - - /** SDMMC0 pin Card Clock (CK) */ - palSetGroupMode(PIOA, (1u << 0), 0U, PAL_SAMA_FUNC_PERIPH_A); - - /** SDMMC0 pin Card Command (CMD) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN1), 0U, - PAL_SAMA_FUNC_PERIPH_A | PAL_MODE_INPUT_PULLUP); - - /** SDMMC0 pin Card Reset (RSTN) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN10), 0U, - PAL_SAMA_FUNC_PERIPH_A | PAL_MODE_INPUT_PULLUP); - - /** SDMMC0 pin VDD Selection (VDDSEL) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN11), 0U, - PAL_SAMA_FUNC_PERIPH_A); - - /** SDMMC0 pin 8-bit Data (DA0-7) */ - palSetGroupMode(PIOA, 0x000003fc, 0U, - PAL_SAMA_FUNC_PERIPH_A | PAL_MODE_INPUT_PULLUP); -#endif - res = 1; - - } - break; - case SDMMC_SLOT1: { - - uint32_t caps0 = BOARD_SDMMC1_CAPS0; - - /* Program capabilities for SDMMC1 */ - sdmmc_set_capabilities(SDMMC1, caps0, CAPS0_MASK, 0, 0); - -#if 0 - /* Configure SDMMC1 pins */ - /** SDMMC1 pin Card Detect (CD) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN30), 0U, - PAL_SAMA_FUNC_PERIPH_E | PAL_MODE_INPUT_PULLUP); - - /** SDMMC1 pin Card Clock (CK) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN22), 0U, PAL_SAMA_FUNC_PERIPH_E); - - /** SDMMC1 pin Card Command (CMD) */ - palSetGroupMode(PIOA, (1u << PIOA_PIN28), 0U, - PAL_SAMA_FUNC_PERIPH_E | PAL_MODE_INPUT_PULLUP); - - /** SDMMC1 pin 4-bit Data (DA0-3) */ - palSetGroupMode(PIOA, 0x003c0000, 0U, - PAL_SAMA_FUNC_PERIPH_E | PAL_MODE_INPUT_PULLUP); -#endif - - res = 1; - } - break; - default: - res = 0; - break; - } - - return res; -} - -bool sdmmc_device_initialize(SdmmcDriver *driver) -{ - - uint32_t base_freq, power, val; - const uint8_t max_exp = (SDMMC_TCR_DTCVAL_Msk >> SDMMC_TCR_DTCVAL_Pos) - 1; - uint8_t exp; - - driver->use_set_blk_cnt = false; - - val = (driver->regs->SDMMC_CA0R & SDMMC_CA0R_MAXBLKL_Msk) >> SDMMC_CA0R_MAXBLKL_Pos; - - driver->blk_size = (val <= 0x2 ? (512 << val) : 512); - - /* Perform the initial I/O calibration sequence, manually. - * Allow tSTARTUP = 2 usec for the analog circuitry to start up. - * CNTVAL = fHCLOCK / (4 * (1 / tSTARTUP)) */ - val = SAMA_MCK; - val = ROUND_INT_DIV(val, 4 * 500000UL); - - - osalDbgCheck( (!(val << SDMMC_CALCR_CNTVAL_Pos & ~SDMMC_CALCR_CNTVAL_Msk)) ); - - driver->regs->SDMMC_CALCR = (driver->regs->SDMMC_CALCR & ~SDMMC_CALCR_CNTVAL_Msk & ~SDMMC_CALCR_TUNDIS) | SDMMC_CALCR_CNTVAL(val); - - calibrate_zout(driver->regs); - - /* Set DAT line timeout error to occur after 500 ms waiting delay. - * 500 ms is the timeout value to implement when writing to SDXC cards. - */ - base_freq = (driver->regs->SDMMC_CA0R & SDMMC_CA0R_TEOCLKF_Msk) >> SDMMC_CA0R_TEOCLKF_Pos; - base_freq *= driver->regs->SDMMC_CA0R & SDMMC_CA0R_TEOCLKU ? 1000000UL : 1000UL; - /* 2 ^ (DTCVAL + 13) = TIMEOUT * FTEOCLK = FTEOCLK / 2 */ - val = base_freq / 2; - for (exp = 31, power = 1UL << 31; !(val & power) && power != 0; - exp--, power >>= 1) ; - if (power == 0) { - TRACE_DEBUG("FTEOCLK is unknown\n\r"); - exp = max_exp; - } - else { - exp = exp + 1 - 13; - exp = (uint8_t)min_u32(exp, max_exp); - } - - driver->regs->SDMMC_TCR = (driver->regs->SDMMC_TCR & ~SDMMC_TCR_DTCVAL_Msk) | SDMMC_TCR_DTCVAL(exp); - - TRACE_DEBUG_1("Set DAT line timeout to %lu ms\n\r", (10UL << (exp + 13UL))/ (base_freq / 100UL)); - - /* Reset the peripheral. This will reset almost all registers. - * It doesn't affect I/O calibration however. */ - reset_peripheral(driver); - /* As sdmmc_reset_peripheral deliberately preserves MC1R.FCD, this field - * has yet to be initialized. As the controller may disable outputs - * depending on the state of the card detection input, this input should - * be neutralized when the device is embedded. */ - if ( (driver->regs->SDMMC_CA0R & SDMMC_CA0R_SLTYPE_Msk) == SDMMC_CA0R_SLTYPE_EMBEDDED) - driver->regs->SDMMC_MC1R |= SDMMC_MC1R_FCD; - else - driver->regs->SDMMC_MC1R &= ~SDMMC_MC1R_FCD; - - - - return true; -} -/** - * Run the SDcard initialization sequence. This function runs the - * initialisation procedure and the identification process, then it sets the - * SD card in transfer state to set the block length and the bus width. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code". - * \param pSd Pointer to a SD card driver instance. - */ -uint8_t sdmmc_device_start(SdmmcDriver *drv) -{ - uint32_t freq; - uint8_t error; - - SdParamReset(&drv->card); - - /* Power the device and the bus on */ - HwPowerDevice(drv, SDMMC_PWR_STD); - /* Reset the controller to default timing mode and data bus width */ - HwSetHsMode(drv, SDMMC_TIM_MMC_BC); - - HwSetBusWidth(drv, 1); - /* For device identification, clock the device at fOD */ - freq = 400000ul; - - error = HwSetClock(drv, &freq); - - if (error != SDMMC_OK && error != SDMMC_CHANGED) { - return error; - } - - - /* Initialization delay: The maximum of 1 msec, 74 clock cycles and supply - * ramp up time. Supply ramp up time provides the time that the power is - * built up to the operating level (the bus master supply voltage) and the - * time to wait until the SD card can accept the first command. */ - /* Power On Init Special Command */ - error = CmdPowerOn(drv); - - t_msleep(drv,200); - - if (error) { - return error; - } - - - return SDMMC_OK; -} - -uint8_t sdmmc_device_identify(SdmmcDriver *drv) -{ - uint8_t error; - bool retry = false; - - if (drv->state != MCID_IDLE ) - return SDMMC_STATE; - - Retry: - /* After power-on or CMD0, all cards? - * CMD lines are in input mode, waiting for start bit of the next command. - * The cards are initialized with a default relative card address - * (RCA=0x0000) and with a default driver stage register setting - * (lowest speed, highest driving current capability). */ - error = SdMmcIdentify(drv); - - if (error) { - TRACE_ERROR_1("Identify %s\n\r", SD_StringifyRetCode(error)); - return error; - } - - if ((drv->card.bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD) { - - error = SDMMC_Lib_SdStart(drv, &retry); - /* Handle the case where the both the slot and the device are - * UHS-I-capable, but the system doesn't support powering the - * card off, when SD_DeInit is called. As a result, from the - * device's perspective, the voltage switch sequence has been - * taken already. */ - if (error && retry) { - HwPowerDevice(drv, SDMMC_PWR_STD_VDD_LOW_IO); - - drv->card.bCardSigLevel = 0; - - error = HwSetHsMode(drv, SDMMC_TIM_SD_SDR12); - - HwSetBusWidth(drv, 1); - - if (!error) { - drv->card.bSpeedMode = SDMMC_TIM_SD_SDR12; - goto Retry; - } - } - } - #ifndef SDMMC_TRIM_SDIO - else if (drv->card.bCardType & CARD_TYPE_bmSDIO) - error = SdioInit(drv); - #endif - #ifndef SDMMC_TRIM_MMC - else if ((drv->card.bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC) - error = MmcInit(drv); - #endif - else { - TRACE_ERROR_1("Identify %s\n\r", "failed"); - return SDMMC_NOT_INITIALIZED; - } - if (error) { - TRACE_ERROR_1("Init %s\n\r", SD_StringifyRetCode(error)); - return error; - } - - - drv->card.bStatus = SDMMC_OK; - - return SDMMC_OK; -} - -void sdmmc_device_deInit(SdmmcDriver *drv) -{ - HwReset(drv); - SdParamReset(&drv->card); - - memset(&drv->cmd, 0, sizeof(drv->cmd)); -} - - -/** - * \brief Fetch events from the SDMMC peripheral, handle them, and proceed to - * the subsequent step, w.r.t. the SD/MMC command being processed. - * \warning This implementation suits LITTLE ENDIAN hosts only. - */ - void sdmmc_device_poll(SdmmcDriver *driver) - - { - osalDbgCheck(driver->state != MCID_OFF); - - Sdmmc *regs = driver->regs; - sSdmmcCommand *cmd = &driver->cmd; - uint16_t events, errors, acesr; - bool has_data; - - if (driver->state != MCID_CMD) - return; - //osalDbgCheck(cmd); - has_data = (cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX) || (cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_RX); - - Fetch: - /* Fetch normal events */ - events = regs->SDMMC_NISTR; - - if (driver->expect_auto_end) - { - while ( chSysIsCounterWithinX(chSysGetRealtimeCounterX(),driver->start_cycles ,driver->start_cycles+driver->timeout_cycles) ); - events |= SDMMC_NISTR_CUSTOM_EVT; - } - - if (!events) - return; - //TRACE_1("events %08x\n\r",events); - /* Check the global error flag */ - if (events & SDMMC_NISTR_ERRINT) { - errors = regs->SDMMC_EISTR; - events &= ~SDMMC_NISTR_ERRINT; - /* Clear error interrupts */ - regs->SDMMC_EISTR = errors; - if (errors & SDMMC_EISTR_CURLIM) - cmd->bStatus = SDMMC_NOT_INITIALIZED; - else if (errors & SDMMC_EISTR_CMDCRC) - cmd->bStatus = SDMMC_ERR_IO; - else if (errors & SDMMC_EISTR_CMDTEO) - cmd->bStatus = SDMMC_NO_RESPONSE; - else if (errors & (SDMMC_EISTR_CMDEND | SDMMC_EISTR_CMDIDX)) - cmd->bStatus = SDMMC_ERR_IO; - else if (errors & SDMMC_EISTR_TUNING) - cmd->bStatus = SDMMC_ERR_IO; - /* TODO upon SDMMC_EISTR_TUNING, clear HC2R:SCLKSEL, and perform - * the tuning procedure */ - /* TODO if SDMMC_NISTR_TRFC and only SDMMC_EISTR_DATTEO then - * ignore SDMMC_EISTR_DATTEO */ - else if (errors & SDMMC_EISTR_DATTEO) - cmd->bStatus = SDMMC_ERR_IO; - else if (errors & (SDMMC_EISTR_DATCRC | SDMMC_EISTR_DATEND)) - cmd->bStatus = SDMMC_ERR_IO; - else if (errors & SDMMC_EISTR_ACMD) { - acesr = regs->SDMMC_ACESR; - if (acesr & SDMMC_ACESR_ACMD12NE) - cmd->bStatus = SDMMC_ERR; - else if (acesr & SDMMC_ACESR_ACMDCRC) - cmd->bStatus = SDMMC_ERR_IO; - else if (acesr & SDMMC_ACESR_ACMDTEO) - cmd->bStatus = SDMMC_NO_RESPONSE; - else if (acesr & (SDMMC_ACESR_ACMDEND | SDMMC_ACESR_ACMDIDX)) - cmd->bStatus = SDMMC_ERR_IO; - else - cmd->bStatus = SDMMC_ERR; - } - else if (errors & SDMMC_EISTR_ADMA) { - //#if TRACE_LEVEL >= TRACE_LEVEL_ERROR - // const uint32_t desc_ix = (regs->SDMMC_ASA0R - - // (uint32_t)set->table) / (SDMMC_DMADL_SIZE * 4UL); - // - // trace_error("ADMA error 0x%x at desc. line[%lu]\n\r", - // regs->SDMMC_AESR, desc_ix); - //#endif - cmd->bStatus = SDMMC_PARAM; - } - else if (errors & SDMMC_EISTR_BOOTAE) - cmd->bStatus = SDMMC_STATE; - else - cmd->bStatus = SDMMC_ERR; - driver->state = cmd->bCmd == 12 ? MCID_LOCKED : MCID_ERROR; - //TRACE_3("CMD%u ended with error flags %04x, cmd status %s\n\r", cmd->bCmd, errors, SD_StringifyRetCode(cmd->bStatus)); - goto End; - } - - /* No error. Give priority to the low-latency event that signals the - * completion of the Auto CMD12 command, hence of the whole multiple- - * block data transfer. */ - if (events & SDMMC_NISTR_CUSTOM_EVT) { - //#ifndef NDEBUG - // if (!(set->regs->SDMMC_PSR & SDMMC_PSR_CMDLL)) - // trace_warning("Auto command still ongoing\n\r"); - //#endif - if (cmd->pResp) { - //TRACE("getting resp\r\n"); - sdmmc_get_response(driver, cmd, true, cmd->pResp); - } - goto Succeed; - } - - /* First, expect completion of the command */ - if (events & SDMMC_NISTR_CMDC) { - //#ifndef NDEBUG - // if (cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX - // && !set->table && set->blk_index != cmd->wNbBlocks - // && !(regs->SDMMC_PSR & SDMMC_PSR_WTACT)) - // trace_warning("Write transfer not started\n\r"); - // else if (cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_RX - // && !set->table && set->blk_index != cmd->wNbBlocks - // && !(regs->SDMMC_PSR & SDMMC_PSR_RTACT)) - // trace_warning("Read transfer not started\n\r"); - //#endif - /* Clear this normal interrupt */ - regs->SDMMC_NISTR = SDMMC_NISTR_CMDC; - events &= ~SDMMC_NISTR_CMDC; - driver->cmd_line_released = true; - /* Retrieve command response */ - if (cmd->pResp) { - //TRACE("getting resp..\r\n"); - sdmmc_get_response(driver, cmd, driver->dat_lines_released, - cmd->pResp); - } - if ((!has_data && !cmd->cmdOp.bmBits.checkBsy) - || driver->dat_lines_released) - goto Succeed; - } - - /* Expect the next incoming block of data */ - if (events & SDMMC_NISTR_BRDRDY - && cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_RX && !driver->config->dma_table) { - /* FIXME may be optimized by looping while PSR.BUFRDEN == 1 */ - uint8_t *in, *out, *bound; - union uint32_u val; - uint16_t count; - - /* Clear this normal interrupt */ - regs->SDMMC_NISTR = SDMMC_NISTR_BRDRDY; - events &= ~SDMMC_NISTR_BRDRDY; - - if (driver->blk_index >= cmd->wNbBlocks) { - // trace_error("Excess of incoming data\n\r"); - cmd->bStatus = SDMMC_ERR_IO; - driver->state = MCID_ERROR; - goto End; - } - out = cmd->pData + driver->blk_index * (uint32_t)cmd->wBlockSize; - count = cmd->wBlockSize & ~0x3; - for (bound = out + count; out < bound; out += 4) { - //#ifndef NDEBUG - // if (!(regs->SDMMC_PSR & SDMMC_PSR_BUFRDEN)) - // trace_error("Unexpected Buffer Read Disable status\n\r"); - //#endif - val.word = regs->SDMMC_BDPR; - out[0] = val.bytes[0]; - out[1] = val.bytes[1]; - out[2] = val.bytes[2]; - out[3] = val.bytes[3]; - } - if (count < cmd->wBlockSize) { - //#ifndef NDEBUG - // if (!(regs->SDMMC_PSR & SDMMC_PSR_BUFRDEN)) - // trace_error("Unexpected Buffer Read Disable status\n\r"); - //#endif - val.word = regs->SDMMC_BDPR; - count = cmd->wBlockSize - count; - for (in = val.bytes, bound = out + count; - out < bound; in++, out++) - *out = *in; - } - #if 0 && !defined(NDEBUG) - if (regs->SDMMC_PSR & SDMMC_PSR_BUFRDEN) - trace_warning("Renewed Buffer Read Enable status\n\r"); - #endif - driver->blk_index++; - } - - /* Expect the Buffer Data Port to be ready to accept the next - * outgoing block of data */ - if (events & SDMMC_NISTR_BWRRDY - && cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX && !driver->config->dma_table - && driver->blk_index < cmd->wNbBlocks) { - /* FIXME may be optimized by looping while PSR.BUFWREN == 1 */ - uint8_t *in, *out, *bound; - union uint32_u val; - uint16_t count; - - /* Clear this normal interrupt */ - regs->SDMMC_NISTR = SDMMC_NISTR_BWRRDY; - events &= ~SDMMC_NISTR_BWRRDY; - - in = cmd->pData + driver->blk_index * (uint32_t)cmd->wBlockSize; - count = cmd->wBlockSize & ~0x3; - for (bound = in + count; in < bound; in += 4) { - val.bytes[0] = in[0]; - val.bytes[1] = in[1]; - val.bytes[2] = in[2]; - val.bytes[3] = in[3]; - //#ifndef NDEBUG - // if (!(regs->SDMMC_PSR & SDMMC_PSR_BUFWREN)) - // trace_error("Unexpected Buffer Write Disable status\n\r"); - //#endif - regs->SDMMC_BDPR = val.word; - } - if (count < cmd->wBlockSize) { - count = cmd->wBlockSize - count; - for (val.word = 0, out = val.bytes, bound = in + count; - in < bound; in++, out++) - *out = *in; - //#ifndef NDEBUG - // if (!(regs->SDMMC_PSR & SDMMC_PSR_BUFWREN)) - // trace_error("Unexpected Buffer Write Disable status\n\r"); - //#endif - regs->SDMMC_BDPR = val.word; - } - #if 0 && !defined(NDEBUG) - if (regs->SDMMC_PSR & SDMMC_PSR_BUFWREN) - trace_warning("Renewed Buffer Write Enable status\n\r"); - #endif - driver->blk_index++; - } - //#ifndef NDEBUG - // else if (events & SDMMC_NISTR_BWRRDY - // && cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX && !set->table - // && set->blk_index >= cmd->wNbBlocks) - // trace_warning("Excess Buffer Write Ready status\n\r"); - //#endif - - /* Expect completion of either the data transfer or the busy state. */ - if (events & SDMMC_NISTR_TRFC) { - /* Deviation from the SD Host Controller Specification: - * the Auto CMD12 command/response (when enabled) is still in - * progress. We are on our own to figure out when CMD12 will - * have completed. - * In the meantime: - * 1. errors affecting the CMD12 command - essentially - * SDMMC_EISTR_ACMD - have not been detected yet. - * 2. SDMMC_RR[3] is not yet valid. - * Our workaround here consists in generating a third event - * further to Transfer Complete, after a predefined amount of - * time, sufficient for CMD12 to complete. - * Refer to sdmmc_send_command(), which has prepared our Timer/ - * Counter for this purpose. */ - if (has_data && (cmd->bCmd == 18 || cmd->bCmd == 25) - && !driver->use_set_blk_cnt) { - - driver->expect_auto_end = true; - //#ifndef NDEBUG - // if (!set->cmd_line_released) - // trace_warning("Command still ongoing\n\r"); - //#endif - } - //#ifndef NDEBUG - // if (regs->SDMMC_PSR & SDMMC_PSR_WTACT) - // trace_error("Write transfer still active\n\r"); - // if (regs->SDMMC_PSR & SDMMC_PSR_RTACT) - // trace_error("Read transfer still active\n\r"); - //#endif - /* Clear this normal interrupt */ - regs->SDMMC_NISTR = SDMMC_NISTR_TRFC; - events &= ~SDMMC_NISTR_TRFC; - driver->dat_lines_released = true; - /* Deviation from the SD Host Controller Specification: - * there are cases, notably CMD7 with address and R1b, where the - * Transfer Complete interrupt precedes Command Complete. In - * such cases, the command/response is still in progress, we - * shall wait for Command Complete. */ - if (driver->cmd_line_released && !driver->expect_auto_end && cmd->pResp) { - //TRACE("getting resp...\r\n"); - sdmmc_get_response(driver, cmd, true, cmd->pResp); - } - if (has_data && !driver->config->dma_table - && driver->blk_index != cmd->wNbBlocks) { - //trace_error("Incomplete data transfer\n\r"); - cmd->bStatus = SDMMC_ERR_IO; - driver->state = MCID_ERROR; - goto End; - } - if (driver->cmd_line_released && !driver->expect_auto_end) - goto Succeed; - } - - //#ifndef NDEBUG - // if (events) - // trace_warning("Unhandled NISTR events: 0x%04x\n\r", events); - //#endif - if (events) - regs->SDMMC_NISTR = events; - goto Fetch; - - Succeed: - driver->state = MCID_LOCKED; - End: - /* Clear residual normal interrupts, if any */ - if (events) - regs->SDMMC_NISTR = events; - #if 0 && !defined(NDEBUG) - if (set->resp_len == 1) - trace_debug("CMD%u got response %08lx\n\r", cmd->bCmd, - cmd->pResp[0]); - else if (set->resp_len == 4) - trace_debug("CMD%u got response %08lx %08lx %08lx %08lx\n\r", - cmd->bCmd, cmd->pResp[0], cmd->pResp[1], cmd->pResp[2], - cmd->pResp[3]); - #endif - /* Upon error, recover by resetting the CMD and DAT lines */ - if (cmd->bStatus != SDMMC_OK && cmd->bStatus != SDMMC_CHANGED) { - /* Resetting DAT lines also aborts the DMA transfer - if any - - * and resets the DMA circuit. */ - regs->SDMMC_SRR |= SDMMC_SRR_SWRSTDAT | SDMMC_SRR_SWRSTCMD; - while (regs->SDMMC_SRR & (SDMMC_SRR_SWRSTDAT - | SDMMC_SRR_SWRSTCMD)) ; - } else if (cmd->bCmd == 0 || (cmd->bCmd == 6 - && cmd->dwArg & 1ul << 31 && !cmd->cmdOp.bmBits.checkBsy)) { - /* Currently in the function switching period, wait for the - * delay preconfigured in sdmmc_send_command(). */ - - while ( chSysIsCounterWithinX(chSysGetRealtimeCounterX(),driver->start_cycles ,driver->start_cycles+driver->timeout_cycles) ); - - } - - /* Release this command */ - - driver->resp_len = 0; - driver->blk_index = 0; - driver->cmd_line_released = false; - driver->dat_lines_released = false; - driver->expect_auto_end = false; - - } - - void sdmmc_set_device_clock(SdmmcDriver *driver, uint32_t freq) - { - osalDbgCheck(freq); - - Sdmmc *regs = driver->regs; - uint32_t base_freq, div, low_freq, up_freq, new_freq; - uint32_t mult_freq, p_div, p_mode_freq; - uint16_t shval; - bool use_prog_mode = false; - - freq = min_u32(freq, 120000000ul); - - if (!(regs->SDMMC_PCR & SDMMC_PCR_SDBPWR)) { - TRACE_ERROR("Bus is off\n\r"); - } - if (regs->SDMMC_HC2R & SDMMC_HC2R_PVALEN) { - TRACE_ERROR("Preset values enabled though not implemented\n\r"); - } - - /* In the Divided Clock Mode scenario, compute the divider */ - base_freq = (regs->SDMMC_CA0R & SDMMC_CA0R_BASECLKF_Msk) >> SDMMC_CA0R_BASECLKF_Pos; - base_freq *= 1000000UL; - /* DIV = FBASECLK / (2 * FSDCLK) */ - div = base_freq / (2 * freq); - if (div >= 0x3ff) - div = 0x3ff; - else { - up_freq = base_freq / (div == 0 ? 1UL : 2 * div); - low_freq = base_freq / (2 * (div + 1UL)); - if (up_freq > freq && (up_freq - freq) > (freq - low_freq)) - div += 1; - } - new_freq = base_freq / (div == 0 ? 1UL : 2 * div); - - /* Now, in the Programmable Clock Mode scenario, compute the divider. - * First, retrieve the frequency of the Generated Clock feeding this - * peripheral. */ - /* TODO fix CLKMULT value in CA1R capability register: the default value - * is 32 whereas the real value is 40.5 */ - mult_freq = (regs->SDMMC_CA1R & SDMMC_CA1R_CLKMULT_Msk) >> SDMMC_CA1R_CLKMULT_Pos; - if (mult_freq != 0) - #if 0 - mult_freq = base_freq * (mult_freq + 1); - #else - mult_freq = SAMA_MCK ;// pmc_get_gck_clock(ID_SDMMC0+driver->config->slot_id); - #endif - if (mult_freq != 0) { - /* DIV = FMULTCLK / FSDCLK - 1 */ - p_div = CEIL_INT_DIV(mult_freq, freq); - if (p_div > 0x3ff) - p_div = 0x3ff; - else if (p_div != 0) - p_div = p_div - 1; - p_mode_freq = mult_freq / (p_div + 1); - if (ABS_DIFF(freq, p_mode_freq) < ABS_DIFF(freq, new_freq)) { - use_prog_mode = true; - div = p_div; - new_freq = p_mode_freq; - } - } - - /* Stop the output clock, so we can change the frequency. - * Deviation from the SD Host Controller Specification: if the internal - * clock was temporarily disabled, the controller would then switch to - * an irrelevant clock frequency. - * This issue has been observed, notably, when trying to switch from 25 - * to 50 MHz. Keep the SDMMC internal clock enabled. */ - shval = regs->SDMMC_CCR & ~SDMMC_CCR_SDCLKEN; - regs->SDMMC_CCR = shval; - driver->dev_freq = new_freq; - use_prog_mode = false; //no generated clock - /* Select the clock mode */ - if (use_prog_mode) - shval |= SDMMC_CCR_CLKGSEL; - else - shval &= ~SDMMC_CCR_CLKGSEL; - /* Set the clock divider, and start the SDMMC internal clock - if it - * wasn't started yet. */ - shval = (shval & ~SDMMC_CCR_USDCLKFSEL_Msk & ~SDMMC_CCR_SDCLKFSEL_Msk) - | SDMMC_CCR_USDCLKFSEL(div >> 8) | SDMMC_CCR_SDCLKFSEL(div & 0xff) - | SDMMC_CCR_INTCLKEN; - regs->SDMMC_CCR = shval; - while (!(regs->SDMMC_CCR & SDMMC_CCR_INTCLKS)) ; - /* Now start the output clock */ - regs->SDMMC_CCR |= SDMMC_CCR_SDCLKEN; - } - - - - - /** - * Here is the fSdmmcSendCommand-type callback. - * SD/MMC command. - * \param _set Pointer to driver instance data (struct sdmmc_set). - * \param cmd Pointer to the command to be sent. Owned by the caller. Shall - * remain valid until the command is completed or stopped. For commands which - * transfer data, mind the peripheral and DMA alignment requirements that the - * external data buffer shall meet. Especially when DMA is used to read from the - * device, in which case the buffer shall be aligned on entire cache lines. - * \return Return code, from the eSDMMC_RC enumeration. If SDMMC_OK, the command - * has been issued and the caller should: - * 1. poll on sdmmc_is_busy(), - * 2. once finished, check the result of the command in cmd->bStatus. - * TODO in future when libsdmmc will set it: call sSdmmcCommand::fCallback. - */ - uint32_t sdmmc_device_command(SdmmcDriver *driver) - { - osalDbgCheck(driver->cmd.bCmd <= 63); - - Sdmmc *regs = driver->regs; - - const bool stop_xfer = driver->cmd.cmdOp.bmBits.xfrData == SDMMC_CMD_STOPXFR; - - const bool has_data = (driver->cmd.cmdOp.bmBits.xfrData == SDMMC_CMD_TX) || (driver->cmd.cmdOp.bmBits.xfrData == SDMMC_CMD_RX); - - const bool use_dma = (bool) (driver->use_polling == false) && - (driver->cmd.bCmd != 21 || driver->tim_mode >= SDMMC_TIM_SD_DS) && - (driver->cmd.bCmd != 19 || driver->tim_mode < SDMMC_TIM_SD_DS); - - const bool wait_switch = (driver->cmd.bCmd == 0) || - (driver->cmd.bCmd == 6 && driver->cmd.dwArg & 1ul << 31 && !driver->cmd.cmdOp.bmBits.checkBsy); - - const bool multiple_xfer = (driver->cmd.bCmd == 18 ) || ( driver->cmd.bCmd == 25 ); - - const bool blk_count_prefix = (driver->cmd.bCmd == 18 || driver->cmd.bCmd == 25) && driver->use_set_blk_cnt; - - const bool stop_xfer_suffix = (driver->cmd.bCmd == 18 || driver->cmd.bCmd == 25) && !driver->use_set_blk_cnt; - - uint32_t eister; - uint32_t mask; - uint32_t len; - uint16_t cr; - uint16_t tmr; - - uint8_t mc1r; - uint8_t rc = SDMMC_OK; - - TRACE_DEBUG_1("[command] start %d\r\n",driver->cmd.bCmd); - - if (driver->state == MCID_OFF) - return SDMMC_STATE; - - if (driver->cmd.cmdOp.bmBits.powerON == driver->cmd.cmdOp.bmBits.sendCmd) { - //trace_error("Invalid command\n\r"); - return SDMMC_PARAM; - } - if (stop_xfer && driver->cmd.bCmd != 12 && driver->cmd.bCmd != 52) { - //trace_error("Inconsistent abort command\n\r"); - return SDMMC_PARAM; - } - if (driver->cmd.cmdOp.bmBits.powerON) { - /* Special call, no command to send this time */ - /* Wait for 74 SD Clock cycles, as per SD Card specification. - * The e.MMC Electrical Standard specifies tRSCA >= 200 usec. */ - if (driver->dev_freq == 0) { - //trace_error("Shall enable the device clock first\n\r"); - return SDMMC_STATE; - } - - return SDMMC_OK; - } - - if (has_data && (driver->cmd.wNbBlocks == 0 || driver->cmd.wBlockSize == 0 - || driver->cmd.pData == NULL)) { - //trace_error("Invalid data\n\r"); - return SDMMC_PARAM; - } - if (has_data && driver->cmd.wBlockSize > driver->blk_size) { - //trace_error("%u-byte data block size not supported\n\r", driver->cmd.wBlockSize); - return SDMMC_PARAM; - } - - if (has_data && use_dma) { - /* Using DMA. Prepare the descriptor table. */ - rc = sdmmc_build_dma_table(driver); - - if (rc != SDMMC_OK && rc != SDMMC_CHANGED) - return rc; - - len = (uint32_t)driver->cmd.wNbBlocks * (uint32_t)driver->cmd.wBlockSize; - - if (driver->cmd.cmdOp.bmBits.xfrData == SDMMC_CMD_TX) { - /* Ensure the outgoing data can be fetched directly from - * RAM */ - cacheCleanRegion(driver->cmd.pData, len); - } - else if (driver->cmd.cmdOp.bmBits.xfrData == SDMMC_CMD_RX) { - /* Invalidate the corresponding data cache lines now, so - * this buffer is protected against a global cache clean - * operation, that concurrent code may trigger. - * Warning: until the command is reported as complete, - * no code should read from this buffer, nor from - * variables cached in the same lines. If such - * anticipated reading had to be supported, the data - * cache lines would need to be invalidated twice: both - * now and upon Transfer Complete. */ - if(((uint32_t) driver->cmd.pData & (L1_CACHE_BYTES - 1)) || (len & (L1_CACHE_BYTES - 1))) { - cacheCleanInvalidateRegion(driver->cmd.pData, len); - } - else { - cacheInvalidateRegion(driver->cmd.pData, len); - } - } - } - - ///if (multiple_xfer && !has_data) - // trace_warning("Inconsistent data\n\r"); - if (sdmmc_is_busy(driver)) { - //trace_error("Concurrent command\n\r"); - return SDMMC_BUSY; - } - driver->state = MCID_CMD; - driver->resp_len = 0; - driver->blk_index = 0; - driver->cmd_line_released = false; - driver->dat_lines_released = false; - driver->expect_auto_end = false; - driver->cmd.bStatus = rc; - TRACE_DEBUG_1("command set status %d\r\n",driver->cmd.bStatus); - - tmr = (regs->SDMMC_TMR & ~SDMMC_TMR_MSBSEL & ~SDMMC_TMR_DTDSEL - & ~SDMMC_TMR_ACMDEN_Msk & ~SDMMC_TMR_BCEN & ~SDMMC_TMR_DMAEN) - | SDMMC_TMR_ACMDEN_DIS; - mc1r = (regs->SDMMC_MC1R & ~SDMMC_MC1R_OPD & ~SDMMC_MC1R_CMDTYP_Msk) - | SDMMC_MC1R_CMDTYP_NORMAL; - cr = (regs->SDMMC_CR & ~SDMMC_CR_CMDIDX_Msk & ~SDMMC_CR_CMDTYP_Msk - & ~SDMMC_CR_DPSEL & ~SDMMC_CR_RESPTYP_Msk) - | SDMMC_CR_CMDIDX(driver->cmd.bCmd) | SDMMC_CR_CMDTYP_NORMAL - | SDMMC_CR_CMDICEN | SDMMC_CR_CMDCCEN; - eister = SDMMC_EISTER_BOOTAE | SDMMC_EISTER_TUNING | SDMMC_EISTER_ADMA - | SDMMC_EISTER_ACMD | SDMMC_EISTER_CURLIM | SDMMC_EISTER_DATEND - | SDMMC_EISTER_DATCRC | SDMMC_EISTER_DATTEO | SDMMC_EISTER_CMDIDX - | SDMMC_EISTER_CMDEND | SDMMC_EISTER_CMDCRC | SDMMC_EISTER_CMDTEO; - - if (driver->cmd.cmdOp.bmBits.odON) - mc1r |= SDMMC_MC1R_OPD; - - switch (driver->cmd.cmdOp.bmBits.respType) { - - case 2: - cr |= SDMMC_CR_RESPTYP_RL136; - /* R2 response doesn't include the command index */ - eister &= ~SDMMC_EISTER_CMDIDX; - break; - case 3: - /* R3 response includes neither the command index nor the CRC */ - eister &= ~(SDMMC_EISTER_CMDIDX | SDMMC_EISTER_CMDCRC); - case 1: - case 4: - if (driver->cmd.cmdOp.bmBits.respType == 4 && driver->cmd.cmdOp.bmBits.ioCmd) - /* SDIO R4 response includes neither the command index nor the CRC */ - eister &= ~(SDMMC_EISTER_CMDIDX | SDMMC_EISTER_CMDCRC); - case 5: - case 6: - case 7: - cr |= driver->cmd.cmdOp.bmBits.checkBsy ? SDMMC_CR_RESPTYP_RL48BUSY : SDMMC_CR_RESPTYP_RL48; - break; - default: - /* No response, ignore response time-out error */ - cr |= SDMMC_CR_RESPTYP_NORESP; - eister &= ~SDMMC_EISTER_CMDTEO; - break; - - } - - if (stop_xfer) { - tmr |= SDMMC_TMR_MSBSEL | SDMMC_TMR_BCEN; - /* TODO consider BGCR:STPBGR (pause) */ - /* TODO in case of SDIO consider CR:CMDTYP = ABORT */ - /* Ignore data errors */ - eister = eister & ~SDMMC_EISTER_ADMA & ~SDMMC_EISTER_DATEND - & ~SDMMC_EISTER_DATCRC & ~SDMMC_EISTER_DATTEO; - } - else if (has_data) { - cr |= SDMMC_CR_DPSEL; - tmr |= driver->cmd.cmdOp.bmBits.xfrData == SDMMC_CMD_TX - ? SDMMC_TMR_DTDSEL_WR : SDMMC_TMR_DTDSEL_RD; - if (blk_count_prefix) - tmr = (tmr & ~SDMMC_TMR_ACMDEN_Msk) - | SDMMC_TMR_ACMDEN_ACMD23; - else if (stop_xfer_suffix) - tmr = (tmr & ~SDMMC_TMR_ACMDEN_Msk) - | SDMMC_TMR_ACMDEN_ACMD12; - /* TODO check if this is fine for SDIO too (byte or block transfer) (driver->cmd.cmdOp.bmBits.ioCmd, driver->cmd.wBlockSize) */ - if (multiple_xfer || driver->cmd.wNbBlocks > 1) - tmr |= SDMMC_TMR_MSBSEL | SDMMC_TMR_BCEN; - if (use_dma) - tmr |= SDMMC_TMR_DMAEN; - } - - /* Wait for the CMD and DATn lines to be ready. If a previous command - * is still being processed, mind the status flags it may raise. */ - mask = SDMMC_PSR_CMDINHC; - if (has_data || (driver->cmd.cmdOp.bmBits.checkBsy && !stop_xfer)) - mask |= SDMMC_PSR_CMDINHD; - - while (regs->SDMMC_PSR & mask) ; - - /* Enable normal interrupts */ - regs->SDMMC_NISTER |= SDMMC_NISTER_BRDRDY | SDMMC_NISTER_BWRRDY - | SDMMC_NISTER_TRFC | SDMMC_NISTER_CMDC; - - osalDbgCheck(!(regs->SDMMC_NISTER & SDMMC_NISTR_CUSTOM_EVT)); - /* Enable error interrupts */ - - regs->SDMMC_EISTER = eister; - /* Clear all interrupt status flags */ - regs->SDMMC_NISTR = SDMMC_NISTR_ERRINT | SDMMC_NISTR_BOOTAR - | SDMMC_NISTR_CINT | SDMMC_NISTR_CREM | SDMMC_NISTR_CINS - | SDMMC_NISTR_BRDRDY | SDMMC_NISTR_BWRRDY | SDMMC_NISTR_DMAINT - | SDMMC_NISTR_BLKGE | SDMMC_NISTR_TRFC | SDMMC_NISTR_CMDC; - - regs->SDMMC_EISTR = SDMMC_EISTR_BOOTAE | SDMMC_EISTR_TUNING - | SDMMC_EISTR_ADMA | SDMMC_EISTR_ACMD | SDMMC_EISTR_CURLIM - | SDMMC_EISTR_DATEND | SDMMC_EISTR_DATCRC | SDMMC_EISTR_DATTEO - | SDMMC_EISTR_CMDIDX | SDMMC_EISTR_CMDEND | SDMMC_EISTR_CMDCRC - | SDMMC_EISTR_CMDTEO; - - /* Issue the command */ - if (has_data) { - if (blk_count_prefix) - regs->SDMMC_SSAR = SDMMC_SSAR_ARG2(driver->cmd.wNbBlocks); - - if (use_dma) - regs->SDMMC_ASA0R = SDMMC_ASA0R_ADMASA((uint32_t)driver->config->dma_table); - - regs->SDMMC_BSR = (regs->SDMMC_BSR & ~SDMMC_BSR_BLKSIZE_Msk) | SDMMC_BSR_BLKSIZE(driver->cmd.wBlockSize); - } - - if (stop_xfer) - regs->SDMMC_BCR = SDMMC_BCR_BLKCNT(0); - else if (has_data && (multiple_xfer || driver->cmd.wNbBlocks > 1)) - regs->SDMMC_BCR = SDMMC_BCR_BLKCNT(driver->cmd.wNbBlocks); - - regs->SDMMC_ARG1R = driver->cmd.dwArg; - - if (has_data || stop_xfer) - regs->SDMMC_TMR = tmr; - - regs->SDMMC_MC1R = mc1r; - regs->SDMMC_CR = cr; - - /* In the case of Auto CMD12, we'll need to generate an extra event. - * Have our Timer/Counter ready for this. */ - if (has_data && stop_xfer_suffix) { - /* Considering the multiple block read mode, - * 1. Assuming Transfer Complete is raised upon successful - * reception of the End bit of the last data packet, - * 2. A SD/eMMC protocol analyzer shows that the CMD12 command - * token is fully transmitted 1 or 2 device clock cycles - * later, - * 3. The device may take up to 64 clock cycles (NCR) before - * initiating the CMD12 response token, - * 4. The code length of the CMD12 response token (R1) is 48 - * bits, hence 48 device clock cycles. - * The sum of the above timings is the maximum time CMD12 will - * take to complete. */ - - driver->timeout_cycles = 2+64+48; - driver->start_cycles = chSysGetRealtimeCounterX(); - - - } - /* With SD devices, the 8-cycle function switching period will apply, - * further to both SWITCH_FUNC and GO_IDLE_STATE commands. - * Note that MMC devices don't require this fixed delay, but regarding - * GO_IDLE_STATE we have no mean to filter the MMC requests out. */ - else if (wait_switch) { - - driver->timeout_ticks = 8; - driver->start_cycles = chSysGetRealtimeCounterX(); - - } - if (!driver->use_polling) { - regs->SDMMC_NISIER |= SDMMC_NISIER_BRDRDY | SDMMC_NISIER_BWRRDY | SDMMC_NISIER_TRFC | SDMMC_NISIER_CMDC | SDMMC_NISIER_CINT; - regs->SDMMC_EISIER = eister; - } - - TRACE_DEBUG_1("[command] finish %d OK\r\n",driver->cmd.bCmd); - return SDMMC_OK; - } - - - - /** - * Here is the fSdmmcIOCtrl-type callback. - * IO control functions. - * \param _set Pointer to driver instance data (struct sdmmc_set). - * \param bCtl IO control code. - * \param param IO control parameter. Optional, depends on the IO control code. - * \return Return code, from the eSDMMC_RC enumeration. - */ - uint32_t sdmmc_device_control(SdmmcDriver *driver, uint32_t bCtl) - { - - uint32_t rc = SDMMC_OK; - - uint8_t byte; - - - if (bCtl != SDMMC_IOCTL_BUSY_CHECK && bCtl != SDMMC_IOCTL_GET_DEVICE) { - TRACE_DEBUG_2("SDMMC_IOCTL_%s(%lu)\n\r", SD_StringifyIOCtrl(bCtl),driver->control_param ); - } - - - switch (bCtl) { - case SDMMC_IOCTL_GET_DEVICE: - - if ((driver->regs->SDMMC_CA0R & SDMMC_CA0R_SLTYPE_Msk) == SDMMC_CA0R_SLTYPE_EMBEDDED) - driver->control_param = 1; - else - driver->control_param = driver->regs->SDMMC_PSR & SDMMC_PSR_CARDINS ? 1 : 0; - break; - - case SDMMC_IOCTL_GET_WP: - - if ((driver->regs->SDMMC_CA0R & SDMMC_CA0R_SLTYPE_Msk) == SDMMC_CA0R_SLTYPE_EMBEDDED) - driver->control_param = 1; - else - driver->control_param = driver->regs->SDMMC_PSR & SDMMC_PSR_WRPPL ? 1 : 0; - break; - - case SDMMC_IOCTL_POWER: - - if (driver->control_param > SDMMC_PWR_STD_VDD_LOW_IO) - return SDMMC_PARAM; - if (driver->control_param == SDMMC_PWR_OFF) - rc = unplug_device(driver); - else if (driver->control_param == SDMMC_PWR_STD_VDD_LOW_IO && !(driver->regs->SDMMC_CA0R & SDMMC_CA0R_V18VSUP)) - return SDMMC_PARAM; - else { - /* Power the device on, or change signaling level. - * This can't be done without configuring the timing - * mode at the same time. */ - byte = driver->tim_mode; - if ((driver->regs->SDMMC_CA0R & (SDMMC_CA0R_V18VSUP| SDMMC_CA0R_V30VSUP| SDMMC_CA0R_V33VSUP)) != SDMMC_CA0R_V18VSUP) { - if (driver->control_param == SDMMC_PWR_STD_VDD_LOW_IO) { - if (byte < SDMMC_TIM_SD_DS) - byte = SDMMC_TIM_MMC_HS200; - else if (byte < SDMMC_TIM_SD_SDR12) - byte = SDMMC_TIM_SD_SDR12; - } - else { - if (byte > SDMMC_TIM_SD_HS) - byte = SDMMC_TIM_SD_DS; - else if (byte > SDMMC_TIM_MMC_HS_DDR - && byte < SDMMC_TIM_SD_DS) - byte = SDMMC_TIM_MMC_BC; - } - } - rc = sdmmc_set_speed_mode(driver, byte, true); - } - break; - - case SDMMC_IOCTL_RESET: - /* Release the device. The device may have been removed. */ - rc = unplug_device(driver); - break; - - case SDMMC_IOCTL_GET_BUSMODE: - byte = sdmmc_get_bus_width(driver); - driver->control_param = byte; - break; - - case SDMMC_IOCTL_SET_BUSMODE: - if (driver->control_param > 0xff) - return SDMMC_PARAM; - rc = sdmmc_set_bus_width(driver, driver->control_param); - TRACE_DEBUG_1("Using a %u-bit data bus\n\r", sdmmc_get_bus_width(driver)); - break; - - case SDMMC_IOCTL_GET_HSMODE: - - if (driver->control_param > 0xff) { - driver->control_param = 0; - break; - } - - byte = (uint8_t)driver->control_param; - - if (byte == SDMMC_TIM_MMC_BC || byte == SDMMC_TIM_SD_DS) { - driver->control_param = 1; - } - else if ((byte == SDMMC_TIM_MMC_HS_SDR - || byte == SDMMC_TIM_MMC_HS_DDR || byte == SDMMC_TIM_SD_HS) - && driver->regs->SDMMC_CA0R & SDMMC_CA0R_HSSUP) - driver->control_param = 1; - else if (byte == SDMMC_TIM_MMC_HS200 - && (driver->regs->SDMMC_CA0R & (SDMMC_CA0R_V18VSUP - | SDMMC_CA0R_V30VSUP | SDMMC_CA0R_V33VSUP)) - == SDMMC_CA0R_V18VSUP - && driver->regs->SDMMC_CA1R & (SDMMC_CA1R_SDR50SUP - | SDMMC_CA1R_DDR50SUP | SDMMC_CA1R_SDR104SUP)) - driver->control_param = 1; - /* TODO rely on platform code to get the data bus width to the - * SD slot, and deny UHS-I timing modes if the DAT[3:0] signals - * are not all routed. */ - else if ((byte == SDMMC_TIM_SD_SDR12 - || byte == SDMMC_TIM_SD_SDR25) - && driver->regs->SDMMC_CA0R & SDMMC_CA0R_V18VSUP - && driver->regs->SDMMC_CA1R & (SDMMC_CA1R_SDR50SUP - | SDMMC_CA1R_DDR50SUP | SDMMC_CA1R_SDR104SUP)) - driver->control_param= 1; - else if (byte == SDMMC_TIM_SD_SDR50 - && driver->regs->SDMMC_CA0R & SDMMC_CA0R_V18VSUP - && driver->regs->SDMMC_CA1R & SDMMC_CA1R_SDR50SUP) - driver->control_param = 1; - else if (byte == SDMMC_TIM_SD_DDR50 - && driver->regs->SDMMC_CA0R & SDMMC_CA0R_V18VSUP - && driver->regs->SDMMC_CA1R & SDMMC_CA1R_DDR50SUP) - driver->control_param = 1; - else if (byte == SDMMC_TIM_SD_SDR104 - && driver->regs->SDMMC_CA0R & SDMMC_CA0R_V18VSUP - && driver->regs->SDMMC_CA1R & SDMMC_CA1R_SDR104SUP) - driver->control_param = 1; - else - driver->control_param = 0; - break; - - case SDMMC_IOCTL_SET_HSMODE: - - if (driver->control_param > 0xff) - return SDMMC_PARAM; - rc = sdmmc_set_speed_mode(driver, (uint8_t)driver->control_param, false); - driver->control_param= driver->tim_mode; - break; - - case SDMMC_IOCTL_SET_CLOCK: - - if (driver->control_param == 0) - return SDMMC_PARAM; - - sdmmc_set_device_clock(driver, driver->control_param); - - TRACE_DEBUG_1("Clocking the device at %lu Hz\n\r", driver->dev_freq); - if (driver->dev_freq > 95000000ul - && (driver->tim_mode == SDMMC_TIM_MMC_HS200 - || driver->tim_mode == SDMMC_TIM_SD_SDR104 - || (driver->tim_mode == SDMMC_TIM_SD_SDR50 - && driver->regs->SDMMC_CA1R & SDMMC_CA1R_TSDR50))) - rc = tuneSampling(driver); - /* TODO setup periodic re-tuning */ - if (driver->dev_freq != driver->control_param) { - rc = rc == SDMMC_OK ? SDMMC_CHANGED : rc; - driver->control_param = driver->dev_freq; - } - break; - - case SDMMC_IOCTL_SET_LENPREFIX: - - driver->use_set_blk_cnt = driver->control_param ? true : false; - driver->control_param = driver->use_set_blk_cnt ? 1 : 0; - break; - - case SDMMC_IOCTL_GET_XFERCOMPL: - - driver->control_param = 1; - break; - - case SDMMC_IOCTL_BUSY_CHECK: - - if (driver->state == MCID_OFF) - driver->control_param = 0; - else - { - - if (driver->use_polling) { - sdmmc_device_poll(driver); - } - if (driver->state == MCID_CMD) { - driver->control_param =1; - } - else { - driver->control_param = 0; - } - - } - break; - - case SDMMC_IOCTL_CANCEL_CMD: - if (driver->state == MCID_OFF) - rc = SDMMC_STATE; - else - rc = CancelCommand(driver); - break; - - case SDMMC_IOCTL_GET_CLOCK: - case SDMMC_IOCTL_SET_BOOTMODE: - case SDMMC_IOCTL_GET_BOOTMODE: - default: - rc = SDMMC_NOT_SUPPORTED; - break; - } - - if (rc != SDMMC_OK && rc != SDMMC_CHANGED - && bCtl != SDMMC_IOCTL_BUSY_CHECK) { - TRACE_ERROR_2("SDMMC_IOCTL_%s ended with %s\n\r",SD_StringifyIOCtrl(bCtl), SD_StringifyRetCode(rc)); - } - - return rc; - } - - void sdmmc_device_sleep(SdmmcDriver *driver,uint32_t t,uint32_t m) - { - systime_t time, end, now; - uint32_t f = 0; - - (void)driver; - - time = chVTGetSystemTimeX(); - - if (m==1) - end = time + TIME_MS2I(t); - else if (m==2) - end = time + TIME_US2I(t); - else - end = time + (systime_t)t; - - do { - - now = chVTGetSystemTimeX(); /* chVTTimeElapsedSinceX(time) */ - - if (now >= end) { - f = 1; - } - - } while (!f); - - } - - void sdmmc_device_startTimeCount(SdmmcDriver *driver) - { - if (driver->timeout_elapsed != -1) { - driver->time = chVTGetSystemTimeX(); - driver->now = driver->time; - } - } - -void sdmmc_device_checkTimeCount(SdmmcDriver *driver) -{ - if (driver->timeout_elapsed != -1) { - - driver->timeout_elapsed = 0; - driver->now = chVTTimeElapsedSinceX(driver->time); - if (driver->now >= driver->timeout_ticks ) { - driver->timeout_elapsed = 1; - } - - } -} - - static void calibrate_zout(Sdmmc * regs) - { - uint32_t calcr; - - /* FIXME find out if this operation should be carried with PCR:SDBPWR - * set and/or the device clock started. */ - - /* CALCR:CNTVAL has been configured by sdmmc_initialize() */ - regs->SDMMC_CALCR |= SDMMC_CALCR_EN; - do - calcr = regs->SDMMC_CALCR; - while (calcr & SDMMC_CALCR_EN); - //trace_debug("Output Z calibr. CALN=%lu CALP=%lu\n\r", - // (calcr & SDMMC_CALCR_CALN_Msk) >> SDMMC_CALCR_CALN_Pos, - // (calcr & SDMMC_CALCR_CALP_Msk) >> SDMMC_CALCR_CALP_Pos); - } - - void reset_peripheral(SdmmcDriver *driver) - { - - uint32_t calcr; - uint8_t mc1r, tcr; - - /* First, save the few settings we'll want to restore. */ - mc1r = driver->regs->SDMMC_MC1R; - tcr = driver->regs->SDMMC_TCR; - calcr = driver->regs->SDMMC_CALCR; - - /* Reset our state variables to match reset values of the registers */ - driver->tim_mode = driver->tim_mode >= SDMMC_TIM_SD_DS ? SDMMC_TIM_SD_DS - : SDMMC_TIM_MMC_BC; - - /* Reset the peripheral. This will reset almost all registers. */ - driver->regs->SDMMC_SRR |= SDMMC_SRR_SWRSTALL; - while (driver->regs->SDMMC_SRR & SDMMC_SRR_SWRSTALL) ; - - /* Restore specific register fields */ - if (mc1r & SDMMC_MC1R_FCD) - driver->regs->SDMMC_MC1R |= SDMMC_MC1R_FCD; - driver->regs->SDMMC_TCR = (driver->regs->SDMMC_TCR & ~SDMMC_TCR_DTCVAL_Msk) - | (tcr & SDMMC_TCR_DTCVAL_Msk); - driver->regs->SDMMC_CALCR = (driver->regs->SDMMC_CALCR & ~SDMMC_CALCR_CNTVAL_Msk - & ~SDMMC_CALCR_TUNDIS) | (calcr & SDMMC_CALCR_CNTVAL_Msk); - - /* Apply our unconditional custom settings */ - /* When using DMA, use the 32-bit Advanced DMA 2 mode */ - driver->regs->SDMMC_HC1R = (driver->regs->SDMMC_HC1R & ~SDMMC_HC1R_DMASEL_Msk) - | SDMMC_HC1R_DMASEL_ADMA32; - /* Configure maximum AHB burst size */ - driver->regs->SDMMC_ACR = (driver->regs->SDMMC_ACR & ~SDMMC_ACR_BMAX_Msk) - | SDMMC_ACR_BMAX_INCR16; - } - - - - void sdmmc_set_capabilities( - Sdmmc * regs, - uint32_t caps0, uint32_t caps0_mask, - uint32_t caps1, uint32_t caps1_mask) - { - osalDbgCheck((caps0 & caps0_mask) == caps0); - osalDbgCheck((caps1 & caps1_mask) == caps1); - - caps0 = (regs->SDMMC_CA0R & ~caps0_mask) | (caps0 & caps0_mask); - caps1 = (regs->SDMMC_CA1R & ~caps1_mask) | (caps1 & caps1_mask); - - regs->SDMMC_CACR = SDMMC_CACR_KEY(0x46) | SDMMC_CACR_CAPWREN; - if (regs->SDMMC_CA0R != caps0) - regs->SDMMC_CA0R = caps0; - if (regs->SDMMC_CA1R != caps1) - regs->SDMMC_CA1R = caps1; - regs->SDMMC_CACR = SDMMC_CACR_KEY(0x46) | 0; - } - - /** - * \brief Retrieve command response from the SDMMC peripheral. - */ - static void sdmmc_get_response(SdmmcDriver *driver, sSdmmcCommand *cmd, bool complete, uint32_t *out) - { - //osalDbgCheck(set); - osalDbgCheck(cmd); - osalDbgCheck(cmd->cmdOp.bmBits.respType <= 7); - osalDbgCheck(out); - - const bool first_call = driver->resp_len == 0; - const bool has_data = cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX - || cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_RX; - uint32_t resp; - uint8_t ix; - - if (first_call) { - switch (cmd->cmdOp.bmBits.respType) { - case 2: - /* R2 response is 120-bit long, split in - * 32+32+32+24 bits this way: - * RR[0] = R[ 39: 8] - * RR[1] = R[ 71: 40] - * RR[2] = R[103: 72] - * RR[3] = R[127:104] - * Shift data the way libsdmmc expects it, - * that is: - * pResp[0] = R[127: 96] - * pResp[1] = R[ 95: 64] - * pResp[2] = R[ 63: 32] - * pResp[3] = R[ 31: 0] - * The CRC7 and the end bit aren't provided, - * just hard-code their default values. */ - out[3] = 0x000000ff; - for (ix = 0; ix < 4; ix++) { - resp = driver->regs->SDMMC_RR[ix]; - if (ix < 3) - out[2 - ix] = resp >> 24 & 0xff; - out[3 - ix] |= resp << 8 & 0xffffff00; - } - driver->resp_len = 4; - break; - case 1: case 3: case 4: case 5: case 6: case 7: - /* The nominal response is 32-bit long */ - out[0] = driver->regs->SDMMC_RR[0]; - driver->resp_len = 1; - break; - case 0: - default: - break; - } - } - - if (has_data && (cmd->bCmd == 18 || cmd->bCmd == 25) && ((first_call - && driver->use_set_blk_cnt) || (complete && !driver->use_set_blk_cnt))) { - resp = driver->regs->SDMMC_RR[3]; - #if 0 - trace_debug("Auto CMD%d returned status 0x%lx\n\r", - set->use_set_blk_cnt ? 23 : 12, resp); - #endif - if (!driver->use_set_blk_cnt) - /* We return a single response to the application: the - * device status returned by CMD18 or CMD25, combined - * with the device status just returned by Auto CMD12. - * Retain the status bits from only CMD18 or CMD25, and - * combine the exception bits from both. */ - out[0] |= resp & ~STAT_DEVICE_IS_LOCKED - & ~STAT_CARD_ECC_DISABLED & ~STAT_CURRENT_STATE - & ~STAT_READY_FOR_DATA & ~STAT_EXCEPTION_EVENT - & ~STAT_APP_CMD; - //#ifndef NDEBUG - // resp = (resp & STAT_CURRENT_STATE) >> 9; - // if (driver->config->use_set_blk_cnt && resp != STATE_TRANSFER) - // trace_warning("Auto CMD23 returned state %lx\n\r", resp); - // else if (!driver->config->use_set_blk_cnt && cmd->bCmd == 18 - // && resp != STATE_SENDING_DATA) - // trace_warning("CMD18 switched to state %lx\n\r", resp); - // else if (!driver->config->use_set_blk_cnt && cmd->bCmd == 25 - /// && resp != STATE_RECEIVE_DATA && resp != STATE_PROGRAMMING) - // trace_warning("CMD25 switched to state %lx\n\r", resp); - //#endif - } - } - -bool sdmmc_is_busy(SdmmcDriver *driver) -{ - //osalDbgCheck(driver->state != MCID_OFF); - - if (driver->use_polling) - sdmmc_device_poll(driver); - if (driver->state == MCID_CMD) - return true; - return false; -} - - -static uint8_t sdmmc_build_dma_table( SdmmcDriver *driver ) -{ - //assert(set); - //assert(set->table); - //assert(set->table_size); - //assert(cmd->pData); - //assert(cmd->wBlockSize); - //assert(cmd->wNbBlocks); - sSdmmcCommand *cmd = &driver->cmd; - uint32_t *line = NULL; - uint32_t data_len = (uint32_t)cmd->wNbBlocks - * (uint32_t)cmd->wBlockSize; - uint32_t ram_addr = (uint32_t)cmd->pData; - uint32_t ram_bound = ram_addr + data_len; - uint32_t line_ix, line_cnt; - uint8_t rc = SDMMC_OK; - -#if 0 - trace_debug("Configuring DMA for a %luB transfer %s %p\n\r", - data_len, cmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX ? "from" : "to", - cmd->pData); -#endif - /* Verify that cmd->pData is word-aligned */ - if ((uint32_t)cmd->pData & 0x3) - return SDMMC_PARAM; - /* Compute the size of the descriptor table for this transfer */ - line_cnt = (data_len - 1 + SDMMC_DMADL_TRAN_LEN_MAX)/ SDMMC_DMADL_TRAN_LEN_MAX; - /* If it won't fit into the allocated buffer, resize the transfer */ - if (line_cnt > driver->config->dma_table_size) { - line_cnt = driver->config->dma_table_size; - data_len = line_cnt * SDMMC_DMADL_TRAN_LEN_MAX; - data_len /= cmd->wBlockSize; - if (data_len == 0) - return SDMMC_NOT_SUPPORTED; - cmd->wNbBlocks = (uint16_t)data_len; - data_len *= cmd->wBlockSize; - ram_bound = ram_addr + data_len; - rc = SDMMC_CHANGED; - } - /* Fill the table */ - for (line_ix = 0, line = driver->config->dma_table; line_ix < line_cnt; - line_ix++, line += SDMMC_DMADL_SIZE) { - if (line_ix + 1 < line_cnt) { - line[0] = SDMMC_DMA0DL_LEN_MAX - | SDMMC_DMA0DL_ATTR_ACT_TRAN - | SDMMC_DMA0DL_ATTR_VALID; - line[1] = SDMMC_DMA1DL_ADDR(ram_addr); - ram_addr += SDMMC_DMADL_TRAN_LEN_MAX; - } - else { - line[0] = ram_bound - ram_addr - < SDMMC_DMADL_TRAN_LEN_MAX - ? SDMMC_DMA0DL_LEN(ram_bound - ram_addr) - : SDMMC_DMA0DL_LEN_MAX; - line[0] |= SDMMC_DMA0DL_ATTR_ACT_TRAN - | SDMMC_DMA0DL_ATTR_END | SDMMC_DMA0DL_ATTR_VALID; - line[1] = SDMMC_DMA1DL_ADDR(ram_addr); - } -#if 0 - trace_debug("DMA descriptor: %luB @ 0x%lx%c\n\r", - (line[0] & SDMMC_DMA0DL_LEN_Msk) >> SDMMC_DMA0DL_LEN_Pos, - line[1], line[0] & SDMMC_DMA0DL_ATTR_END ? '.' : ' '); -#endif - } - return rc; -} - -static uint8_t unplug_device(SdmmcDriver *driver) -{ - //osalDbgCheck(set); - - Sdmmc *regs = driver->regs; - uint32_t usec = 0; - uint8_t mc1r; - - //trace_debug("Release and power the device off\n\r"); - if (driver->state == MCID_CMD) - CancelCommand(driver); - - /* Hardware-reset the e.MMC, move it to the pre-idle state. - * Note that this will only be effective on systems where - * 1) the RST_n e.MMC input is wired to the SDMMCx_RSTN PIO, and - * 2) the hardware reset functionality of the device has been - * enabled by software (!) Refer to ECSD register byte 162. */ - /* Generate a pulse on SDMMCx_RSTN. Satisfy tRSTW >= 1 usec. - * The timer driver can't cope with periodic interrupts triggered as - * frequently as one interrupt per microsecond. Extend to 10 usec. */ - mc1r = regs->SDMMC_MC1R; - regs->SDMMC_MC1R = mc1r | SDMMC_MC1R_RSTN; - t_usleep(driver,10); - regs->SDMMC_MC1R = mc1r; - /* Wait for either tRSCA = 200 usec or 74 device clock cycles, as per - * the e.MMC Electrical Standard. */ - if (driver->dev_freq != 0) - usec = ROUND_INT_DIV(74 * 1000000UL, driver->dev_freq); - usec = max_u32(usec, 200); - t_usleep(driver,usec); - - /* Stop both the output clock and the SDMMC internal clock */ - regs->SDMMC_CCR &= ~(SDMMC_CCR_SDCLKEN | SDMMC_CCR_INTCLKEN); - driver->dev_freq = 0; - /* Cut the power rail supplying signals to/from the device */ - regs->SDMMC_PCR &= ~SDMMC_PCR_SDBPWR; - /* Reset the peripheral. This will reset almost all registers. */ - reset_peripheral(driver); - - driver->state = MCID_OFF; - return SDMMC_OK; -} - - -/** - * \brief Switch to the specified timing mode - * \note Since HC2R:VS18EN and HC2R:UHSMS fields depend on each other, this - * function simultaneously updates the timing mode and the electrical state of - * host I/Os. - * \param set Pointer to the driver instance data - * \param mode The new timing mode - * \param verify When switching from high to low signaling level, expect - * the host input levels driven by the device to conform to the VOLTAGE_SWITCH - * standard sequence. - * \return A \ref sdmmc_rc result code - */ -static uint8_t sdmmc_set_speed_mode(SdmmcDriver *driver, uint8_t mode,bool verify) -{ - //osalDbgCheck(set); - - Sdmmc *regs = driver->regs; - const uint32_t caps = regs->SDMMC_CA0R; - /* Deviation from the SD Host Controller Specification: we use the - * Voltage Support capabilities to indicate the supported signaling - * levels (VCCQ), rather than the power supply voltage (VCC). */ - const bool perm_low_sig = (caps & (SDMMC_CA0R_V18VSUP - | SDMMC_CA0R_V30VSUP | SDMMC_CA0R_V33VSUP)) == SDMMC_CA0R_V18VSUP; - uint32_t usec = 0; - uint16_t hc2r_prv, hc2r; - uint8_t rc = SDMMC_OK, hc1r_prv, hc1r, mc1r_prv, mc1r, pcr_prv, pcr; - bool toggle_sig_lvl, low_sig, dev_clk_on; - - if ((mode > SDMMC_TIM_MMC_HS200 && mode < SDMMC_TIM_SD_DS) - || mode > SDMMC_TIM_SD_SDR104) - return SDMMC_PARAM; - if ((mode == SDMMC_TIM_MMC_HS200 - || (mode >= SDMMC_TIM_SD_SDR12 && mode <= SDMMC_TIM_SD_SDR104)) - && !(caps & SDMMC_CA0R_V18VSUP)) - return SDMMC_PARAM; - -#if 0 - /* FIXME The datasheet is unclear about CCR:DIV restriction when the MMC - * timing mode is High Speed DDR */ - if ((mode == SDMMC_TIM_MMC_HS_SDR || mode == SDMMC_TIM_MMC_HS_DDR - || mode == SDMMC_TIM_SD_HS) && !(regs->SDMMC_CCR - & (SDMMC_CCR_USDCLKFSEL_Msk | SDMMC_CCR_SDCLKFSEL_Msk))) { - TRACE_ERROR("Incompatible with the current clock config\n\r"); - return SDMMC_STATE; - } -#endif - - driver->state = (driver->state == MCID_OFF) ? MCID_IDLE : driver->state; - - mc1r = mc1r_prv = regs->SDMMC_MC1R; - hc1r = hc1r_prv = regs->SDMMC_HC1R; - hc2r = hc2r_prv = regs->SDMMC_HC2R; - pcr = pcr_prv = regs->SDMMC_PCR; - mc1r = (mc1r & ~SDMMC_MC1R_DDR) - | (mode == SDMMC_TIM_MMC_HS_DDR ? SDMMC_MC1R_DDR : 0); - hc1r = (hc1r & ~SDMMC_HC1R_HSEN) | (mode == SDMMC_TIM_MMC_HS_SDR - || mode == SDMMC_TIM_SD_HS ? SDMMC_HC1R_HSEN : 0); - hc2r = hc2r & ~SDMMC_HC2R_DRVSEL_Msk & ~SDMMC_HC2R_VS18EN - & ~SDMMC_HC2R_UHSMS_Msk; - if (mode == SDMMC_TIM_MMC_HS200 - || (mode >= SDMMC_TIM_SD_SDR12 && mode <= SDMMC_TIM_SD_SDR104)) - hc2r |= SDMMC_HC2R_VS18EN; - if (mode == SDMMC_TIM_MMC_HS200 || mode == SDMMC_TIM_SD_SDR104) - hc2r |= SDMMC_HC2R_UHSMS_SDR104; - else if (mode == SDMMC_TIM_SD_SDR12) - hc2r |= SDMMC_HC2R_UHSMS_SDR12; - else if (mode == SDMMC_TIM_SD_SDR25) - hc2r |= SDMMC_HC2R_UHSMS_SDR25; - else if (mode == SDMMC_TIM_SD_SDR50) - hc2r |= SDMMC_HC2R_UHSMS_SDR50; - else if (mode == SDMMC_TIM_SD_DDR50) - hc2r |= SDMMC_HC2R_UHSMS_DDR50; - /* Use the fixed clock when sampling data. Except if we keep using - * a 100+ MHz device clock. */ - if (driver->dev_freq <= 95000000ul || (mode != SDMMC_TIM_MMC_HS200 - && mode != SDMMC_TIM_SD_SDR104 && (mode != SDMMC_TIM_SD_SDR50 - || !(regs->SDMMC_CA1R & SDMMC_CA1R_TSDR50)))) - hc2r &= ~SDMMC_HC2R_SCLKSEL; - /* On SAMA5D2-XULT when using 1.8V signaling, on host outputs choose - * Driver Type C, i.e. 66 ohm nominal output impedance. - * FIXME rely on platform code to retrieve the optimal host output - * Driver Type. It depends on board design. An oscilloscope should be - * set up to observe signal integrity, then among the driver types that - * meet rise and fall time requirements, the weakest should be selected. - */ - if (hc2r & SDMMC_HC2R_VS18EN) - hc2r |= SDMMC_HC2R_DRVSEL_TYPEC; - pcr = (pcr & ~SDMMC_PCR_SDBVSEL_Msk) | SDMMC_PCR_SDBPWR; - low_sig = perm_low_sig || hc2r & SDMMC_HC2R_VS18EN; - if (low_sig) - pcr |= SDMMC_PCR_SDBVSEL_18V; - else - pcr |= caps & SDMMC_CA0R_V30VSUP ? SDMMC_PCR_SDBVSEL_30V - : SDMMC_PCR_SDBVSEL_33V; - - if (hc2r == hc2r_prv && hc1r == hc1r_prv && mc1r == mc1r_prv - && pcr == pcr_prv) - goto End; - toggle_sig_lvl = pcr_prv & SDMMC_PCR_SDBPWR - && (pcr ^ pcr_prv) & SDMMC_PCR_SDBVSEL_Msk; - if (!(pcr_prv & SDMMC_PCR_SDBPWR)) { - TRACE_DEBUG("Power the device on\n\r"); - } - else if (toggle_sig_lvl) { - TRACE_DEBUG_1("Signaling level going %s\n\r", - hc2r & SDMMC_HC2R_VS18EN ? "low" : "high"); - } - if (verify && toggle_sig_lvl && hc2r & SDMMC_HC2R_VS18EN) { - /* Expect this call to follow the VOLTAGE_SWITCH command; - * allow 2 device clock periods before the device pulls the CMD - * and DAT[3:0] lines down */ - if (driver->dev_freq != 0) - usec = ROUND_INT_DIV(2 * 1000000UL, driver->dev_freq); - usec = max_u32(usec, 10); - t_usleep(driver,usec); - if (regs->SDMMC_PSR & (SDMMC_PSR_CMDLL | SDMMC_PSR_DATLL_Msk)) - rc = SDMMC_STATE; - } - /* Avoid generating glitches on the device clock */ - dev_clk_on = regs->SDMMC_CCR & SDMMC_CCR_SDCLKEN - && (toggle_sig_lvl || hc2r_prv & SDMMC_HC2R_PVALEN - || hc2r != hc2r_prv); - if (dev_clk_on) - regs->SDMMC_CCR &= ~SDMMC_CCR_SDCLKEN; - if (toggle_sig_lvl) - /* Drive the device clock low, turn CMD and DATx high-Z */ - regs->SDMMC_PCR = pcr & ~SDMMC_PCR_SDBPWR; - - /* Now change the timing mode */ - if (mc1r != mc1r_prv) - regs->SDMMC_MC1R = mc1r; - if (hc1r != hc1r_prv) - regs->SDMMC_HC1R = hc1r; - if (hc2r != hc2r_prv) - regs->SDMMC_HC2R = hc2r; - if (toggle_sig_lvl) { - /* Changing the signaling level. The SD Host Controller - * Specification requires the HW to stabilize the electrical - * levels within 5 ms, which equals 5 system ticks. - * Alternative: wait for tPRUL = 25 ms */ - t_msleep(driver,5); - if (hc2r & SDMMC_HC2R_VS18EN - && !(regs->SDMMC_HC2R & SDMMC_HC2R_VS18EN)) - rc = SDMMC_ERR; - } - if (pcr != pcr_prv) - regs->SDMMC_PCR = pcr; - if (verify && toggle_sig_lvl && hc2r & SDMMC_HC2R_VS18EN) { - t_msleep(driver,1); - if (regs->SDMMC_PSR & (SDMMC_PSR_CMDLL | SDMMC_PSR_DATLL_Msk)) - rc = SDMMC_STATE; - } - if (dev_clk_on || (toggle_sig_lvl && hc2r & SDMMC_HC2R_VS18EN)) - /* FIXME verify that current dev clock freq is 400 kHz */ - regs->SDMMC_CCR |= SDMMC_CCR_SDCLKEN; - if (toggle_sig_lvl && hc2r & SDMMC_HC2R_VS18EN) { - /* Expect the device to release the CMD and DAT[3:0] lines - * within 1 ms */ - t_msleep(driver,1); - if ((regs->SDMMC_PSR & (SDMMC_PSR_CMDLL | SDMMC_PSR_DATLL_Msk)) - != (SDMMC_PSR_CMDLL | SDMMC_PSR_DATLL_Msk) && verify) - rc = SDMMC_STATE; - if (!dev_clk_on) - regs->SDMMC_CCR &= ~SDMMC_CCR_SDCLKEN; - } - TRACE_DEBUG_1("Using timing mode 0x%02x\n\r", mode); - - regs->SDMMC_CALCR = (regs->SDMMC_CALCR & ~SDMMC_CALCR_ALWYSON) - | (low_sig ? SDMMC_CALCR_ALWYSON : 0); - if (low_sig || pcr != pcr_prv) - /* Perform the output calibration sequence */ - calibrate_zout(driver->regs); - /* TODO in SDR12-50/DDR50 mode, schedule periodic re-calibration */ - -End: - if (rc == SDMMC_OK) - driver->tim_mode = mode; - return rc; -} - - - - -uint8_t sdmmc_get_bus_width(SdmmcDriver *driver) -{ - //osalDbgCheck(set); - - const uint8_t hc1r = driver->regs->SDMMC_HC1R; - - if (hc1r & SDMMC_HC1R_EXTDW) - return 8; - else if (hc1r & SDMMC_HC1R_DW) - return 4; - else - return 1; -} - -static uint8_t sdmmc_set_bus_width(SdmmcDriver *driver, uint8_t bits) -{ - //osalDbgCheck(set); - - Sdmmc *regs = driver->regs; - uint8_t hc1r_prv, hc1r; - - if (bits != 1 && bits != 4 && bits != 8) - return SDMMC_PARAM; - if (bits == 8 && !(regs->SDMMC_CA0R & SDMMC_CA0R_ED8SUP)) { - //trace_error("This slot doesn't support an 8-bit data bus\n\r"); - return SDMMC_PARAM; - } - /* TODO in case of SD slots, rely on platform code to get the width of - * the data bus actually implemented on the board. In the meantime we - * assume DAT[3:0] are all effectively connected to the device. */ - - hc1r = hc1r_prv = regs->SDMMC_HC1R; - if (bits == 8 && hc1r & SDMMC_HC1R_EXTDW) - return SDMMC_OK; - else if (bits == 8) - hc1r |= SDMMC_HC1R_EXTDW; - else { - hc1r &= ~SDMMC_HC1R_EXTDW; - if (bits == 4) - hc1r |= SDMMC_HC1R_DW; - else - hc1r &= ~SDMMC_HC1R_DW; - if (hc1r == hc1r_prv) - return SDMMC_OK; - } - regs->SDMMC_HC1R = hc1r; - return SDMMC_OK; -} - - - static uint8_t HwReset(SdmmcDriver *driver) - { - uint32_t rc; - - driver->control_param = 0; - - rc = sdmmc_device_control(driver, SDMMC_IOCTL_RESET); - - return rc; - } - - uint8_t HwPowerDevice(SdmmcDriver *drv, uint8_t nowSwitchOn) - { - uint32_t rc; - - drv->control_param = nowSwitchOn; - - rc = sdmmc_device_control(drv, SDMMC_IOCTL_POWER); - - return rc; - } - - uint8_t HwSetHsMode(SdmmcDriver *drv, uint8_t timingMode) - { - uint32_t rc; - - drv->control_param = timingMode; - - rc = sdmmc_device_control(drv, SDMMC_IOCTL_SET_HSMODE); - - if ((rc == SDMMC_OK || rc == SDMMC_CHANGED) - && (drv->control_param > 0xff || drv->control_param != (uint32_t)timingMode)) - rc = SDMMC_CHANGED; - return rc; - } - - uint32_t HwSetBusWidth( SdmmcDriver *drv,uint8_t newWidth) - { - uint32_t rc; - - drv->control_param = newWidth; - - rc = sdmmc_device_control(drv, SDMMC_IOCTL_SET_BUSMODE); - - return rc; - } - - bool HwIsTimingSupported(SdmmcDriver *drv, uint8_t timingMode) - { - uint32_t rc; - - drv->control_param = timingMode; - - rc = sdmmc_device_control(drv, SDMMC_IOCTL_GET_HSMODE); - - return rc == SDMMC_OK ? (drv->control_param ? true : false) : false; - } - - uint8_t HwSetClock(SdmmcDriver *drv, uint32_t * pIoValClk) - { - uint32_t rc; - - drv->control_param = *pIoValClk; - - rc = sdmmc_device_control(drv, SDMMC_IOCTL_SET_CLOCK); - - if (rc == SDMMC_OK || rc == SDMMC_CHANGED) { - - *pIoValClk = drv->control_param; - - TRACE_DEBUG_1("Device clk %lu kHz\n\r", drv->control_param / 1000UL); - } - return rc; - } - - - -#endif diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.h deleted file mode 100644 index d9c789a20..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.h +++ /dev/null @@ -1,384 +0,0 @@ -#ifndef CH_SDMMC_DEVICE_H_ -#define CH_SDMMC_DEVICE_H_ - - -/** \addtogroup sdmmc_ocr_acc SD/MMC OCR register fields (SD 2.0 & MMC 4.3) - * @{ - */ -#define SD_OCR_VDD_LOW (1ul << 7) /**< SD: Reserved for Low Voltage Range */ -#define MMC_OCR_VDD_170_195 (1ul << 7) /**< MMC: 1.7 ~ 1.95V, Dual vol and eMMC is 1 */ -#define MMC_OCR_VDD_200_270 (0x7Ful << 8) /**< MMC: 2.0 ~ 2.7 V */ -#define SD_OCR_VDD_20_21 (1ul << 8) -#define SD_OCR_VDD_21_22 (1ul << 9) -#define SD_OCR_VDD_22_23 (1ul << 10) -#define SD_OCR_VDD_23_24 (1ul << 11) -#define SD_OCR_VDD_24_25 (1ul << 12) -#define SD_OCR_VDD_25_26 (1ul << 13) -#define SD_OCR_VDD_26_27 (1ul << 14) -#define SD_OCR_VDD_27_28 (1ul << 15) -#define SD_OCR_VDD_28_29 (1ul << 16) -#define SD_OCR_VDD_29_30 (1ul << 17) -#define SD_OCR_VDD_30_31 (1ul << 18) -#define SD_OCR_VDD_31_32 (1ul << 19) -#define SD_OCR_VDD_32_33 (1ul << 20) -#define SD_OCR_VDD_33_34 (1ul << 21) -#define SD_OCR_VDD_34_35 (1ul << 22) -#define SD_OCR_VDD_35_36 (1ul << 23) - -/** - * sdmmc_speedmode SD/MMC Bus speed modes - * Here lists the MMC, e.MMC and SD bus speed modes. - */ -#define SDMMC_TIM_MMC_BC (0x00) -#define SDMMC_TIM_MMC_HS_SDR (0x01) -#define SDMMC_TIM_MMC_HS_DDR (0x02) -#define SDMMC_TIM_MMC_HS200 (0x03) -#define SDMMC_TIM_SD_DS (0x10) -#define SDMMC_TIM_SD_HS (0x11) -#define SDMMC_TIM_SD_SDR12 (0x12) -#define SDMMC_TIM_SD_SDR25 (0x13) -#define SDMMC_TIM_SD_SDR50 (0x14) -#define SDMMC_TIM_SD_DDR50 (0x15) -#define SDMMC_TIM_SD_SDR104 (0x16) - - -/** - * \addtogroup sdmmc_powermode SD/MMC power supply modes - * Here we list the voltage level configurations we may apply when supplying - * power to the device. - * @{*/ -#define SDMMC_PWR_OFF (0) -#define SDMMC_PWR_STD (1) -#define SDMMC_PWR_STD_VDD_LOW_IO (2) - -/** SD/MMC Low Level IO Control: Check busy. - Must implement for low level driver busy check. - IOCtrl(pSd, SDMMC_IOCTL_BUSY_CHECK, (uint32_t)pBusyFlag) */ -#define SDMMC_IOCTL_BUSY_CHECK 0x0 -/** SD/MMC Low Level IO Control: Power control. - Recommended for SD/MMC/SDIO power control. - IOCtrl(pSd, SDMMC_IOCTL_POWER, (uint32_t)ON/OFF) */ -#define SDMMC_IOCTL_POWER 0x1 -/** SD/MMC Low Level IO Control: Cancel command. - IOCtrl(pSd, SDMMC_IOCTL_CANCEL_CMD, NULL) */ -#define SDMMC_IOCTL_CANCEL_CMD 0x2 -/** SD/MMC Low Level IO Control: Reset & disable HW. - IOCtrl(pSd, SDMMC_IOCTL_RESET, NULL) */ -#define SDMMC_IOCTL_RESET 0x3 -/** SD/MMC Low Level IO Control: Set clock frequency, return applied frequency - Recommended for clock selection - IOCtrl(pSd, SDMMC_IOCTL_SET_CLOCK, (uint32_t*)pIoFreq) */ -#define SDMMC_IOCTL_SET_CLOCK 0x11 -/** SD/MMC Low Level IO Control: Set bus mode, return applied mode - Recommended for bus mode selection - IOCtrl(pSd, SDMMC_IOCTL_SET_BUSMODE, (uint32_t*)pIoBusMode) */ -#define SDMMC_IOCTL_SET_BUSMODE 0x12 -/** SD/MMC Low Level IO Control: Select one of the SDMMC_TIM_x timing modes. - Returns the effective mode, further to this operation. - IOCtrl(pSd, SDMMC_IOCTL_SET_HSMODE, (uint32_t*)pIoTimingMode) */ -#define SDMMC_IOCTL_SET_HSMODE 0x13 -/** SD/MMC Low Level IO Control: Set Boot mode */ -#define SDMMC_IOCTL_SET_BOOTMODE 0x14 -/** SD/MMC Low Level IO Control: Enable or disable implicit SET_BLOCK_COUNT - command, return applied mode. - Recommended with devices that support the SET_BLOCK_COUNT command. - IOCtrl(pSd, SDMMC_IOCTL_SET_LENPREFIX, (uint32_t*)pIoLenPrefix) */ -#define SDMMC_IOCTL_SET_LENPREFIX 0x15 -/** SD/MMC Low Level IO Control: Get clock frequency */ -#define SDMMC_IOCTL_GET_CLOCK 0x21 -/** SD/MMC Low Level IO Control: Bus mode */ -#define SDMMC_IOCTL_GET_BUSMODE 0x22 -/** SD/MMC Low Level IO Control: Query whether the driver supports the specified - SDMMC_TIM_x timing mode. */ -#define SDMMC_IOCTL_GET_HSMODE 0x23 -/** SD/MMC Low Level IO Control: Boot mode */ -#define SDMMC_IOCTL_GET_BOOTMODE 0x24 -/** SD/MMC Low Level IO Control: Query driver capability, whether the driver - implicitly sends the STOP_TRANSMISSION command when multiple-block data - transfers complete successfully. - IOCtrl(pSd, SDMMC_IOCTL_GET_XFERCOMPL, (uint32_t*)pOAutoXferCompletion) */ -#define SDMMC_IOCTL_GET_XFERCOMPL 0x25 -/** SD/MMC Low Level IO Control: Query whether a device is detected in this slot - IOCtrl(pSd, SDMMC_IOCTL_GET_DEVICE, (uint32_t*)pODetected) */ -#define SDMMC_IOCTL_GET_DEVICE 0x26 -/** SD/MMC Low Level IO Control: Query whether the card is writeprotected -or not by mechanical write protect switch */ -#define SDMMC_IOCTL_GET_WP 0x27 -/** @}*/ - -#define SD_IFC_CHK_PATTERN_Pos 0 /**< Check pattern */ -#define SD_IFC_CHK_PATTERN_Msk (0xffu << SD_IFC_CHK_PATTERN_Pos) -#define SD_IFC_CHK_PATTERN_STD (0xaau << 0) -#define SD_IFC_VHS_Pos 8 /**< Host Supplied Voltage range */ -#define SD_IFC_VHS_Msk (0xfu << SD_IFC_VHS_Pos) -#define SD_IFC_VHS_27_36 (0x1u << 8) -#define SD_IFC_VHS_LOW (0x2u << 8) - -/** Get u8 from byte pointed data area */ -#define SD_U8(pD, nBytes, iByte) ( ((uint8_t*)(pD))[(iByte)] ) -/** Get u16 from data area */ -#define SD_U16(pD, nBytes, iByte) \ - ( (uint16_t)((uint8_t*)(pD))[(iByte)] |\ - (uint16_t)((uint8_t*)(pD))[(iByte) + 1] << 8 ) -/**Get u32 from data area */ -#define SD_U32(pD, nBytes, iByte) \ - ( (uint32_t)((uint8_t*)(pD))[(iByte)] |\ - (uint32_t)((uint8_t*)(pD))[(iByte) + 1] << 8 |\ - (uint32_t)((uint8_t*)(pD))[(iByte) + 2] << 16 |\ - (uint32_t)((uint8_t*)(pD))[(iByte) + 3] << 24 ) - - - - -/** \addtogroup mmc_ext_csd MMC Extended CSD byte fields - * @{ - */ -/** MMC Extended CSD access macro: get one byte (512 bytes). */ -#define MMC_EXT8(p, i) SD_U8(p, 512, i) -/** MMC Extended CSD access macro: get one word (512 bytes). */ -#define MMC_EXT32(p, i) SD_U32(p, 512, i) -#define MMC_EXT_S_CMD_SET_I 504 /**< Supported Command Sets slice */ -#define MMC_EXT_S_CMD_SET(p) MMC_EXT8(p, MMC_EXT_S_CMD_SET_I) -#define MMC_EXT_PWR_CL_DDR_52_360_I 239 /**< Power Class for 52MHz DDR @ 3.6V */ -#define MMC_EXT_PWR_CL_DDR_52_360(p) MMC_EXT8(p, MMC_EXT_PWR_CL_DDR_52_360_I) -#define MMC_EXT_PWR_CL_200_195_I 237 /**< Power Class for 200MHz HS200 @ VCCQ=1.95V VCC=3.6V */ -#define MMC_EXT_PWR_CL_200_195(p) MMC_EXT8(p, MMC_EXT_PWR_CL_200_195_I) -#define MMC_EXT_BOOT_INFO_I 228 /**< Boot information slice */ -#define MMC_EXT_BOOT_INFO(p) MMC_EXT8(p, MMC_EXT_BOOT_INFO_I) -#define MMC_EXT_BOOT_SIZE_MULTI_I 226 /**< Boot partition size slice */ -#define MMC_EXT_BOOT_SIZE_MULTI(p) MMC_EXT8(p, MMC_EXT_BOOT_SIZE_MULTI_I) -#define MMC_EXT_ACC_SIZE_I 225 /**< Access size slice */ -#define MMC_EXT_ACC_SIZE(p) MMC_EXT8(p, MMC_EXT_ACC_SIZE_I) -#define MMC_EXT_HC_ERASE_GRP_SIZE_I 224 /**< High-capacity erase time unit size slice */ -#define MMC_EXT_HC_ERASE_GRP_SIZE(p) MMC_EXT8(p, MMC_EXT_HC_ERASE_GRP_SIZE_I) -#define MMC_EXT_ERASE_TIMEOUT_MULT_I 223 /**< High-capacity erase timeout slice */ -#define MMC_EXT_ERASE_TIMEOUT_MULT(p) MMC_EXT8(p, MMC_EXT_ERASE_TIMEOUT_MULT_I) -#define MMC_EXT_REL_WR_SEC_C_I 222 /**< Reliable write sector count slice */ -#define MMC_EXT_REL_WR_SEC_C(p) MMC_EXT8(p, MMC_EXT_REL_WR_SEC_C_I) -#define MMC_EXT_HC_WP_GRP_SIZE_I 221 /**< High-capacity write protect group size slice */ -#define MMC_EXT_HC_WP_GRP_SIZE(p) MMC_EXT8(p, MMC_EXT_HC_WP_GRP_SIZE_I) -#define MMC_EXT_S_C_VCC_I 220 /**< Sleep current (VCC) */ -#define MMC_EXT_S_C_VCC(p) MMC_EXT8(p, MMC_EXT_S_C_VCC_I) -#define MMC_EXT_S_C_VCCQ_I 219 /**< Sleep current (VCC) */ -#define MMC_EXT_S_C_VCCQ(p) MMC_EXT8(p, MMC_EXT_S_C_VCCQ_I) -#define MMC_EXT_S_A_TIMEOUT_I 217 /**< Sleep current (VCCQ) */ -#define MMC_EXT_S_A_TIMEOUT(p) MMC_EXT8(p, MMC_EXT_S_A_TIMEOUT_I) -#define MMC_EXT_SEC_COUNT_I 212 /**< Sector Count slice */ -#define MMC_EXT_SEC_COUNT(p) MMC_EXT32(p, MMC_EXT_SEC_COUNT_I) -#define MMC_EXT_MIN_PERF_W_8_52_I 210 /**< Minimum Write Performance for 8bit @ 52MHz */ -#define MMC_EXT_MIN_PERF_W_8_52(p) MMC_EXT8(p, MMC_EXT_MIN_PERF_W_8_52_I) -#define MMC_EXT_MIN_PERF_R_8_52_I 209 /**< Minimum Read Performance for 8bit @ 52MHz */ -#define MMC_EXT_MIN_PERF_R_8_52(p) MMC_EXT8(p, MMC_EXT_MIN_PERF_R_8_52_I) -#define MMC_EXT_MIN_PERF_W_8_26_4_52_I 208 /**< Minimum Write Performance for 8bit @ 26MHz or 4bit @ 52MHz */ -#define MMC_EXT_MIN_PERF_W_8_26_4_52(p) MMC_EXT8(p, MMC_EXT_MIN_PERF_W_8_26_4_52_I) -#define MMC_EXT_MIN_PERF_R_8_26_4_52_I 207 /**< Minimum Read Performance for 8bit @ 26MHz or 4bit @ 52MHz */ -#define MMC_EXT_MIN_PERF_R_8_26_4_52(p) MMC_EXT8(p, MMC_EXT_MIN_PERF_R_8_26_4_52_I) -#define MMC_EXT_MIN_PERF_W_4_26_I 206 /**< Minimum Write Performance for 4bit @ 26MHz */ -#define MMC_EXT_MIN_PERF_W_4_26(p) MMC_EXT8(p, MMC_EXT_MIN_PERF_W_4_26_I) -#define MMC_EXT_MIN_PERF_R_4_26_I 205 /**< Minimum Read Performance for 4bit @ 26MHz */ -#define MMC_EXT_MIN_PERF_R_4_26(p) MMC_EXT8(p, MMC_EXT_MIN_PERF_R_4_26_I) -#define MMC_EXT_PWR_CL_26_360_I 203 /**< Power Class for 26MHz @ 3.6V */ -#define MMC_EXT_PWR_CL_26_360(p) MMC_EXT8(p, MMC_EXT_PWR_CL_26_360_I) -#define MMC_EXT_PWR_CL_52_360_I 202 /**< Power Class for 52MHz @ 3.6V */ -#define MMC_EXT_PWR_CL_52_360(p) MMC_EXT8(p, MMC_EXT_PWR_CL_52_360_I) -#define MMC_EXT_PWR_CL_26_195_I 201 /**< Power Class for 26MHz @ 1.95V */ -#define MMC_EXT_PWR_CL_26_195(p) MMC_EXT8(p, MMC_EXT_PWR_CL_26_195_I) -#define MMC_EXT_PWR_CL_52_195_I 200 /**< Power Class for 52MHz @ 1.95V */ -#define MMC_EXT_PWR_CL_52_195(p) MMC_EXT8(p, MMC_EXT_PWR_CL_52_195_I) -#define MMC_EXT_DRV_STRENGTH_I 197 /**< Supported I/O driver strength types */ -#define MMC_EXT_DRV_STRENGTH(p) MMC_EXT8(p, MMC_EXT_DRV_STRENGTH_I) -#define MMC_EXT_CARD_TYPE_I 196 /**< Card Type */ -#define MMC_EXT_CARD_TYPE(p) MMC_EXT8(p, MMC_EXT_CARD_TYPE_I) -#define MMC_EXT_CSD_STRUCTURE_I 194 /**< CSD Structure Version */ -#define MMC_EXT_CSD_STRUCTURE(p) MMC_EXT8(p, MMC_EXT_CSD_STRUCTURE_I) -#define MMC_EXT_EXT_CSD_REV_I 192 /**< Extended CSD Revision */ -#define MMC_EXT_EXT_CSD_REV(p) MMC_EXT8(p, MMC_EXT_EXT_CSD_REV_I) -#define MMC_EXT_CMD_SET_I 191 /**< Command Set */ -#define MMC_EXT_CMD_SET(p) MMC_EXT8(p, MMC_EXT_CMD_SET_I) -#define MMC_EXT_CMD_SET_REV_I 189 /**< Command Set Revision */ -#define MMC_EXT_CMD_SET_REV(p) MMC_EXT8(p, MMC_EXT_CMD_SET_REV_I) -#define MMC_EXT_POWER_CLASS_I 187 /**< Power Class */ -#define MMC_EXT_POWER_CLASS(p) MMC_EXT8(p, MMC_EXT_POWER_CLASS_I) -#define MMC_EXT_HS_TIMING_I 185 /**< High Speed Interface Timing */ -#define MMC_EXT_HS_TIMING(p) MMC_EXT8(p, MMC_EXT_HS_TIMING_I) -#define MMC_EXT_HS_TIMING_HS400 0x3 -#define MMC_EXT_HS_TIMING_HS200 0x2 -#define MMC_EXT_HS_TIMING_EN 0x1 -#define MMC_EXT_HS_TIMING_DIS 0x0 -#define MMC_EXT_HS_TIMING_40R 0x40 -#define MMC_EXT_HS_TIMING_100R 0x30 -#define MMC_EXT_HS_TIMING_66R 0x20 -#define MMC_EXT_HS_TIMING_33R 0x10 -#define MMC_EXT_HS_TIMING_50R 0x00 -#define MMC_EXT_BUS_WIDTH_I 183 /**< Bus Width Mode */ -#define MMC_EXT_BUS_WIDTH(p) MMC_EXT8(p, MMC_EXT_BUS_WIDTH_I) -#define MMC_EXT_BUS_WIDTH_1BIT 0 -#define MMC_EXT_BUS_WIDTH_4BITS 1 -#define MMC_EXT_BUS_WIDTH_8BITS 2 -#define MMC_EXT_BUS_WIDTH_DDR 0x4 -#define MMC_EXT_ERASED_MEM_CONT_I 181 /**< Erased Memory Content */ -#define MMC_EXT_ERASED_MEM_CONT(p) MMC_EXT8(p, MMC_EXT_ERASED_MEM_CONT_I) -#define MMC_EXT_BOOT_CONFIG_I 179 /**< Boot configuration slice */ -#define MMC_EXT_BOOT_CONFIG(p) MMC_EXT8(p, MMC_EXT_BOOT_CONFIG_I) -#define MMC_EXT_BOOT_BUS_WIDTH_I 177 /**< Boot bus width slice */ -#define MMC_EXT_BOOT_BUS_WIDTH(p) MMC_EXT8(p, MMC_EXT_BOOT_BUS_WIDTH_I) -#define MMC_EXT_ERASE_GROUP_DEF_I 175 /**< High-density erase group definition */ -#define MMC_EXT_ERASE_GROUP_DEF(p) MMC_EXT8(p, MMC_EXT_ERASE_GROUP_DEF_I) -#define MMC_EXT_BOOT_WP_STATUS_I 174 /**< Current protection status of the boot partitions */ -#define MMC_EXT_BOOT_WP_STATUS(p) MMC_EXT8(p, MMC_EXT_BOOT_WP_STATUS_I) -#define MMC_EXT_DATA_SECTOR_SIZE_I 61 /**< Current sector size */ -#define MMC_EXT_DATA_SECTOR_SIZE(p) MMC_EXT8(p, MMC_EXT_DATA_SECTOR_SIZE_I) -#define MMC_EXT_DATA_SECT_512B 0 -#define MMC_EXT_DATA_SECT_4KIB 1 - - - -#define SD_BITS32(pDw, nbits, ibit, bits) \ - ( (((uint32_t*)(pDw))[(nbits)/32-(ibit)/32-1] >> ((ibit)%32)) & ((uint32_t)(1ul << (bits)) - 1 ) ) - - -/** \addtogroup sdmmc_cid_acc SD/MMC CID register fields - * @{ - */ -/** CID register access (128 bits, 16 * 8 bits, 4 * 32 bits) */ -#define SD_CID(pCid, field, bits) SD_BITS32(pCid, 128, field, bits) -#define SD_CID_MID(pCid) (uint8_t)SD_CID(pCid, 120, 8) /**< Manufacture ID */ -#define eMMC_CID_CBX(pCid) (uint8_t)SD_CID(pCid, 112, 2) /**< eMMC BGA(01)/CARD(00) */ -#define SD_CID_OID1(pCid) (uint8_t)SD_CID(pCid, 112, 8) /**< OEM/App ID Byte 1 */ -#define SD_CID_OID0(pCid) (uint8_t)SD_CID(pCid, 104, 8) /**< OEM/App ID Byte 0 */ -#define MMC_CID_OID(pCid) (uint16_t)SD_CID(pCid, 104, 16) /**< MMC OEM/App ID */ -#define eMMC_CID_OID(pCid) (uint8_t)SD_CID(pCid, 104, 8) /**< MMC v4.3+ OEM/App ID */ -#define SD_CID_PNM4(pCid) (uint8_t)SD_CID(pCid, 96, 8) /**< Product name byte 4 */ -#define SD_CID_PNM3(pCid) (uint8_t)SD_CID(pCid, 88, 8) /**< Product name byte 3 */ -#define SD_CID_PNM2(pCid) (uint8_t)SD_CID(pCid, 80, 8) /**< Product name byte 2 */ -#define SD_CID_PNM1(pCid) (uint8_t)SD_CID(pCid, 72, 8) /**< Product name byte 1 */ -#define SD_CID_PNM0(pCid) (uint8_t)SD_CID(pCid, 64, 8) /**< Product name byte 0 */ -#define MMC_CID_PNM5(pCid) (uint8_t)SD_CID(pCid, 96, 8) /**< Product name byte 5 */ -#define MMC_CID_PNM4(pCid) (uint8_t)SD_CID(pCid, 88, 8) /**< Product name byte 4 */ -#define MMC_CID_PNM3(pCid) (uint8_t)SD_CID(pCid, 80, 8) /**< Product name byte 3 */ -#define MMC_CID_PNM2(pCid) (uint8_t)SD_CID(pCid, 72, 8) /**< Product name byte 2 */ -#define MMC_CID_PNM1(pCid) (uint8_t)SD_CID(pCid, 64, 8) /**< Product name byte 1 */ -#define MMC_CID_PNM0(pCid) (uint8_t)SD_CID(pCid, 56, 8) /**< Product name byte 0 */ - -#define SD_CID_PRV1(pCid) (uint8_t)SD_CID(pCid, 60, 4) /**< Product revision major number */ -#define SD_CID_PRV0(pCid) (uint8_t)SD_CID(pCid, 56, 4) /**< Product revision minor number */ -#define MMC_CID_PRV1(pCid) (uint8_t)SD_CID(pCid, 52, 4) /**< Product revision major number */ -#define MMC_CID_PRV0(pCid) (uint8_t)SD_CID(pCid, 48, 4) /**< Product revision minor number */ - -#define SD_CID_PSN3(pCid) (uint8_t)SD_CID(pCid, 48, 8) /**< Product serial 3 */ -#define SD_CID_PSN2(pCid) (uint8_t)SD_CID(pCid, 40, 8) /**< Product serial 2 */ -#define SD_CID_PSN1(pCid) (uint8_t)SD_CID(pCid, 32, 8) /**< Product serial 1 */ -#define SD_CID_PSN0(pCid) (uint8_t)SD_CID(pCid, 24, 8) /**< Product serial 0 */ -#define MMC_CID_PSN3(pCid) (uint8_t)SD_CID(pCid, 40, 8) /**< Product serial 3 */ -#define MMC_CID_PSN2(pCid) (uint8_t)SD_CID(pCid, 32, 8) /**< Product serial 2 */ -#define MMC_CID_PSN1(pCid) (uint8_t)SD_CID(pCid, 24, 8) /**< Product serial 1 */ -#define MMC_CID_PSN0(pCid) (uint8_t)SD_CID(pCid, 16, 8) /**< Product serial 0 */ - -#define SD_CID_MDT_Y(pCid) (uint8_t)SD_CID(pCid, 12, 8) /**< Manufacturing Year (0=2000) */ -#define SD_CID_MDT_M(pCid) (uint8_t)SD_CID(pCid, 8, 4) /**< Manufacturing month */ -#define MMC_CID_MDT_Y(pCid) (uint8_t)SD_CID(pCid, 8, 4) /**< Manufacturing Year (0=1997 or 2013) */ -#define MMC_CID_MDT_M(pCid) (uint8_t)SD_CID(pCid, 12, 4) /**< Manufacturing month */ - -#define SD_CID_CRC(pCid) (uint8_t)SD_CID(pCid, 1, 7) /**< CRC7 checksum */ -/** @}*/ - -/** CSD register access macros (128 bits, 16 * 8 bits, 4 * 32 bits */ -#define SD_CSD(pCsd, field, bits) SD_BITS32(pCsd, 128, field, bits) -#define SD_CSD_STRUCTURE(pCsd) (uint8_t)SD_CSD(pCsd, 126, 2) /**< CSD structure */ -#define SD_CSD_STRUCTURE_1_0 0 /**< SD v1.01~1.10, v2.0/Std Capacity */ -#define SD_CSD_STRUCTURE_2_0 1 /**< SD v2.0/HC */ -#define MMC_CSD_STRUCTURE_1_0 0 /**< MMC v1.0~1.2 */ -#define MMC_CSD_STRUCTURE_1_1 1 /**< MMC v1.4~2.2 */ -#define MMC_CSD_STRUCTURE_1_2 2 /**< MMC v3.1~3.31(v4.0), v4.1~(>v4.1) */ -#define MMC_CSD_SPEC_VERS(pCsd) (uint8_t)SD_CSD(pCsd, 122, 4) /**< System spec version */ -#define MMC_CSD_SPEC_VERS_1_0 0 /**< MMC v1.0~1.2 */ -#define MMC_CSD_SPEC_VERS_1_4 1 /**< MMC v1.4 */ -#define MMC_CSD_SPEC_VERS_2_0 2 /**< MMC v2.0~2.2 */ -#define MMC_CSD_SPEC_VERS_3_1 3 /**< MMC v3.1~3.31 */ -#define MMC_CSD_SPEC_VERS_4_0 4 /**< MMC v4.0(v4.0), v4.1~(>v4.1) */ -#define SD_CSD_TAAC(pCsd) (uint8_t)SD_CSD(pCsd, 112, 8) /**< Data read-access-time-1 */ -#define SD_CSD_NSAC(pCsd) (uint8_t)SD_CSD(pCsd, 104, 8) /**< Data read access-time-2 in CLK cycles */ -#define SD_CSD_TRAN_SPEED(pCsd) (uint8_t)SD_CSD(pCsd, 96, 8) /**< Max. data transfer rate */ -#define SD_CSD_CCC(pCsd) (uint16_t)SD_CSD(pCsd, 84, 12) /**< Card command class */ -#define SD_CSD_READ_BL_LEN(pCsd) (uint8_t)SD_CSD(pCsd, 80, 4) /**< Max. read data block length */ -#define SD_CSD_READ_BL_PARTIAL(pCsd) (uint8_t)SD_CSD(pCsd, 79, 1) /**< Bartial blocks for read allowed */ -#define SD_CSD_WRITE_BLK_MISALIGN(pCsd) (uint8_t)SD_CSD(pCsd, 78, 1) /**< Write block misalignment */ -#define SD_CSD_READ_BLK_MISALIGN(pCsd) (uint8_t)SD_CSD(pCsd, 77, 1) /**< Read block misalignment */ -#define SD_CSD_DSR_IMP(pCsd) (uint8_t)SD_CSD(pCsd, 76, 1) /**< DSP implemented */ -#define SD_CSD_C_SIZE(pCsd) (uint16_t)((SD_CSD(pCsd, 72, 2) << 10) | \ - (SD_CSD(pCsd, 64, 8) << 2) | \ - SD_CSD(pCsd, 62, 2)) /**< Device size */ -#define SD2_CSD_C_SIZE(pCsd) ((SD_CSD(pCsd, 64, 6) << 16) | \ - (SD_CSD(pCsd, 56, 8) << 8) | \ - SD_CSD(pCsd, 48, 8)) /**< Device size v2.0 */ -#define SD_CSD_VDD_R_CURR_MIN(pCsd) (uint8_t)SD_CSD(pCsd, 59, 3) /**< Max. read current VDD min */ -#define SD_CSD_VDD_R_CURR_MAX(pCsd) (uint8_t)SD_CSD(pCsd, 56, 3) /**< Max. read current VDD max */ -#define SD_CSD_VDD_W_CURR_MIN(pCsd) (uint8_t)SD_CSD(pCsd, 53, 3) /**< Max. write current VDD min */ -#define SD_CSD_VDD_W_CURR_MAX(pCsd) (uint8_t)SD_CSD(pCsd, 50, 3) /**< Max. write current VDD max */ -#define SD_CSD_C_SIZE_MULT(pCsd) (uint8_t)SD_CSD(pCsd, 47, 3) /**< Device size multiplier */ -#define SD_CSD_ERASE_BLK_EN(pCsd) (uint8_t)SD_CSD(pCsd, 46, 1) /**< Erase single block enable */ -#define SD_CSD_SECTOR_SIZE(pCsd) (uint8_t)((SD_CSD(pCsd, 40, 6) << 1) | \ - SD_CSD(pCsd, 39, 1)) /**< Erase sector size*/ -#define SD_CSD_WP_GRP_SIZE(pCsd) (uint8_t)SD_CSD(pCsd, 32, 7) /**< Write protect group size*/ -#define MMC_CSD_ERASE_GRP_SIZE(pCsd) (uint8_t)SD_CSD(pCsd, 42, 5) /**< Erase group size */ -#define MMC_CSD_ERASE_GRP_MULT(pCsd) (uint8_t)SD_CSD(pCsd, 37, 5) /**< Erase group size multiplier */ -#define MMC_CSD_WP_GRP_SIZE(pCsd) (uint8_t)SD_CSD(pCsd, 32, 5) /**< Write protect group size*/ -#define SD_CSD_WP_GRP_ENABLE(pCsd) (uint8_t)SD_CSD(pCsd, 31, 1) /**< write protect group enable*/ -#define MMC_CSD_DEFAULT_ECC(pCsd) (uint8_t)SD_CSD(pCsd, 29, 2) /**< Manufacturer default ECC */ -#define SD_CSD_R2W_FACTOR(pCsd) (uint8_t)SD_CSD(pCsd, 26, 3) /**< Write speed factor*/ -#define SD_CSD_WRITE_BL_LEN(pCsd) (uint8_t)((SD_CSD(pCsd, 24, 2) << 2) | \ - SD_CSD(pCsd, 22, 2)) /**< Max write block length*/ -#define SD_CSD_WRITE_BL_PARTIAL(pCsd) (uint8_t)SD_CSD(pCsd, 21, 1) /**< Partial blocks for write allowed*/ -#define SD_CSD_CONTENT_PROT_APP(pCsd) (uint8_t)SD_CSD(pCsd, 16, 1) /**< File format group*/ -#define SD_CSD_FILE_FORMAT_GRP(pCsd) (uint8_t)SD_CSD(pCsd, 15, 1) /**< File format group*/ -#define SD_CSD_COPY(pCsd) (uint8_t)SD_CSD(pCsd, 14, 1) /**< Copy flag (OTP)*/ -#define SD_CSD_PERM_WRITE_PROTECT(pCsd) (uint8_t)SD_CSD(pCsd, 13, 1) /**< Permanent write protect*/ -#define SD_CSD_TMP_WRITE_PROTECT(pCsd) (uint8_t)SD_CSD(pCsd, 12, 1) /**< Temporary write protection*/ -#define SD_CSD_FILE_FORMAT(pCsd) (uint8_t)SD_CSD(pCsd, 10, 2) /**< File format*/ -#define MMC_CSD_ECC(pCsd) (uint8_t)SD_CSD(pCsd, 8, 2) /**< ECC */ -#define MMC_CSD_ECC_NONE 0 /**< none */ -#define MMC_CSD_ECC_BCH 1 /**< BCH, 3 correctable bits per block */ -#define SD_CSD_CRC(pCsd) (uint8_t)SD_CSD(pCsd, 1, 7) /**< CRC*/ - -#define SD_CSD_MULT(pCsd) (uint16_t)(1u << (SD_CSD_C_SIZE_MULT(pCsd) + 2)) -#define SD_CSD_BLOCKNR(pCsd) ((SD_CSD_C_SIZE(pCsd) + 1ul) * SD_CSD_MULT(pCsd)) -#define SD_CSD_BLOCKNR_HC(pCsd) ((SD2_CSD_C_SIZE(pCsd) + 1ul) * 1024ull) -#define SD_CSD_BLOCK_LEN(pCsd) (uint16_t)(1u << SD_CSD_READ_BL_LEN(pCsd)) -#define SD_CSD_TOTAL_SIZE(pCsd) ((uint64_t)SD_CSD_BLOCKNR(pCsd) * SD_CSD_BLOCK_LEN(pCsd)) -#define SD_CSD_TOTAL_SIZE_HC(pCsd) ((SD2_CSD_C_SIZE(pCsd) + 1ul) * 512ull * 1024ull) -/** @}*/ - - - - -#define t_usleep(d,t) sdmmc_device_sleep(d,t,2) -#define t_msleep(d,t) sdmmc_device_sleep(d,t,1) -#define t_xsleep(d,t) sdmmc_device_sleep(d,t,0) - -extern uint8_t sdmmc_device_lowlevelcfg(SdmmcDriver *driver); -extern bool sdmmc_device_initialize(SdmmcDriver *driver); -extern void sdmmc_device_deInit(SdmmcDriver *drv); -extern void sdmmc_device_poll(SdmmcDriver *driver); -extern uint32_t sdmmc_device_command(SdmmcDriver *driver); -extern uint32_t sdmmc_device_control(SdmmcDriver *driver, uint32_t bCtl); -extern void sdmmc_device_sleep(SdmmcDriver *driver,uint32_t t,uint32_t m); -extern void sdmmc_device_startTimeCount(SdmmcDriver *driver); -extern void sdmmc_device_checkTimeCount(SdmmcDriver *driver); - -extern uint8_t sdmmc_device_start(SdmmcDriver *drv); -extern uint8_t sdmmc_device_identify(SdmmcDriver *drv); - -extern uint8_t sdmmc_get_bus_width(SdmmcDriver *driver); -extern uint8_t HwSetHsMode(SdmmcDriver *drv, uint8_t timingMode); -extern uint32_t HwSetBusWidth( SdmmcDriver *drv,uint8_t newWidth); -extern uint8_t HwSetClock(SdmmcDriver *drv, uint32_t * pIoValClk); -extern uint8_t HwPowerDevice(SdmmcDriver *drv, uint8_t nowSwitchOn); -extern bool HwIsTimingSupported(SdmmcDriver *drv, uint8_t timingMode); -extern uint32_t SdmmcGetMaxFreq(SdmmcDriver *drv); -extern uint8_t SdMmcSelect(SdmmcDriver *drv, uint16_t address, uint8_t statCheck); -extern uint8_t SdMmcIdentify(SdmmcDriver *drv); -extern uint8_t SDMMC_Lib_SdStart(SdmmcDriver *drv, bool * retry); -extern void SdMmcUpdateInformation(SdmmcDriver *drv, bool csd, bool extData); -extern bool sdmmc_is_busy(SdmmcDriver *driver); - -#endif /* CH_SDMMC_DEVICE_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_macros.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_macros.h deleted file mode 100644 index c973d1e4a..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_macros.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef CH_SDMMC_MACROS_H_ -#define CH_SDMMC_MACROS_H_ - - -#if !defined(CACHE_ALIGNED) -#define CACHE_ALIGNED __attribute__((aligned(L1_CACHE_BYTES))) -#endif - -/* - * @brief NO CACHE attribute - */ -#if !defined(NO_CACHE) -#define NO_CACHE __attribute__((section (".nocache"))) -#endif - -#define IS_CACHE_ALIGNED(x) ((((uint32_t)(x)) & (L1_CACHE_BYTES - 1)) == 0) -#if !defined(ROUND_INT_DIV) -#define ROUND_INT_DIV(n,d) (((n) + ((d)-1)) / (d)) -#endif -#define ROUND_UP_MULT(x,m) (((x) + ((m)-1)) & ~((m)-1)) -#define CEIL_INT_DIV(n,d) (((n) + (d) - 1) / (d)) -#define ABS_DIFF(a,b) ((a) < (b) ? (b) - (a) : (a) - (b)) -#define ARRAY_SIZE(x) (sizeof ((x)) / sizeof(*(x))) - -#define _PrintTitle(s) TRACE(s) -#define _PrintField(f,v) TRACE_1(f,v) - -static inline uint32_t max_u32(uint32_t a, uint32_t b) -{ - return a > b ? a : b; -} - -static inline uint32_t min_u32(uint32_t a, uint32_t b) -{ - return a < b ? a : b; -} - -#endif /* CH_SDMMC_MACROS_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.c b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.c deleted file mode 100644 index 7720b4ba3..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.c +++ /dev/null @@ -1,377 +0,0 @@ -#include -#include "hal.h" - -#if (SAMA_USE_SDMMC == TRUE) - -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_cmds.h" -#include "ch_sdmmc_sd.h" - -#ifndef SDMMC_TRIM_MMC - -/** Check if MMC Spec version 4 */ -#define MMC_IsVer4(pSd) ( MMC_CSD_SPEC_VERS(pSd->CSD) >= 4 ) - -/** Check if MMC CSD structure is 1.2 (3.1 or later) */ -#define MMC_IsCSDVer1_2(pSd) \ - ( (SD_CSD_STRUCTURE(pSd->CSD)==2) \ - ||(SD_CSD_STRUCTURE(pSd->CSD)>2&&MMC_EXT_CSD_STRUCTURE(pSd->EXT)>=2) ) - - -/** MMC transfer multiplier factor codes (1/10) list */ - -const uint8_t mmcTransMultipliers[16] = { - 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80 -}; - - -static uint8_t mmcSelectBuswidth(SdmmcDriver *driver, uint8_t busWidth, bool ddr) -{ - uint8_t error; - uint32_t status; - MmcCmd6Arg cmd6Arg = { - .access = 0x3, /* Write byte in the EXT_CSD register */ - .index = MMC_EXT_BUS_WIDTH_I, /* Target byte in EXT_CSD */ - .value = MMC_EXT_BUS_WIDTH_1BIT, /* Byte value */ - }; - - if (busWidth == 8) - cmd6Arg.value = MMC_EXT_BUS_WIDTH_8BITS - | (ddr ? MMC_EXT_BUS_WIDTH_DDR : 0); - else if (busWidth == 4) - cmd6Arg.value = MMC_EXT_BUS_WIDTH_4BITS - | (ddr ? MMC_EXT_BUS_WIDTH_DDR : 0); - else if (busWidth != 1) - return SDMMC_PARAM; - - error = MmcCmd6(driver, &cmd6Arg, &status); - - if (error) - return SDMMC_ERR; - else if (status & STATUS_MMC_SWITCH) - return SDMMC_NOT_SUPPORTED; - - return SDMMC_OK; -} - -static uint8_t mmcDetectBuswidth(SdmmcDriver *driver) -{ - uint8_t error, busWidth, mask = 0xff, i, len; - sSdCard *pSd =&driver->card; - //assert(sizeof(pSd->sandbox1) >= 8); - //assert(sizeof(pSd->sandbox2) >= 8); - - memset(pSd->sandbox1, 0, 8); - for (busWidth = 8; busWidth != 0; busWidth /= busWidth == 8 ? 2 : 4) { - error = HwSetBusWidth(driver, busWidth); - if (error) - continue; - switch (busWidth) { - case 8: - pSd->sandbox1[0] = 0x55; - pSd->sandbox1[1] = 0xaa; - break; - case 4: - pSd->sandbox1[0] = 0x5a; - pSd->sandbox1[1] = 0; - break; - case 1: - pSd->sandbox1[0] = 0x80; - pSd->sandbox1[1] = 0; - break; - } - len = (uint8_t)max_u32(busWidth, 2); - error = Cmd19(driver, pSd->sandbox1, len, NULL); - - if (error) { - /* Devices which do not respond to CMD19 - which results - * in the driver returning SDMMC_ERROR_NORESPONSE - - * simply do not support the bus test procedure. - * When the device responds to CMD19, mind the - * difference with other data write commands: further - * to host data, the device does not emit the CRC status - * token. Typically the peripheral reports the anomaly, - * and the driver is likely to return SDMMC_ERR_IO. */ - if (error != SDMMC_ERR_IO) - return 0; - } - error = Cmd14(driver, pSd->sandbox2, busWidth, NULL); - - if (error) - continue; - if (busWidth == 1) { - mask = 0xc0; - pSd->sandbox2[0] &= mask; - } - len = busWidth == 8 ? 2 : 1; - for (i = 0; i < len; i++) { - if ((pSd->sandbox1[i] ^ pSd->sandbox2[i]) != mask) - break; - } - if (i == len) - break; - } - return busWidth; -} - - -uint8_t MmcGetExtInformation(SdmmcDriver *driver) -{ - sSdCard *pSd = &driver->card; - /* MMC 4.0 Higher version */ - if (SD_CSD_STRUCTURE(pSd->CSD) >= 2 && MMC_IsVer4(pSd)) - return MmcCmd8(driver); - else - return SDMMC_NOT_SUPPORTED; -} - - -uint8_t MmcInit(SdmmcDriver *driver) -{ - MmcCmd6Arg sw_arg = { - .access = 0x3, /* Write byte in the EXT_CSD register */ - }; - uint64_t mem_size; - uint32_t freq, drv_err, status; - uint8_t error, tim_mode, pwr_class, width; - bool flag; - - tim_mode = driver->card.bSpeedMode = SDMMC_TIM_MMC_BC; - /* The host then issues the command ALL_SEND_CID (CMD2) to the card to get - * its unique card identification (CID) number. - * Card that is unidentified (i.e. which is in Ready State) sends its CID - * number as the response (on the CMD line). */ - error = Cmd2(driver); - if (error) - return error; - - /* Thereafter, the host issues SET_RELATIVE_ADDR (CMD3) to assign the - * device a dedicated relative card address (RCA), which is shorter than - * CID and which is used to address the card in the future data transfer - * mode. Once the RCA is received the card state changes to the Stand-by - * State. */ - error = Cmd3(driver); - if (error) - return error; - //else - TRACE_DEBUG_1("RCA=%u\n\r", driver->card.wAddress); - - /* SEND_CSD (CMD9) to obtain the Card Specific Data (CSD register), - * e.g. block length, card storage capacity, etc... */ - error = Cmd9(driver); - if (error) - return error; - - /* Calculate transfer speed */ - freq = SdmmcGetMaxFreq(driver); - - error = HwSetClock(driver, &freq); - - if (error != SDMMC_OK && error != SDMMC_CHANGED) - return error; - - driver->card.dwCurrSpeed = freq; - - /* Now select the card, to TRAN state */ - error = SdMmcSelect(driver, driver->card.wAddress, 0); - if (error) - return error; - - /* If CSD:SPEC_VERS indicates v4.0 or higher, read EXT_CSD */ - error = MmcGetExtInformation(driver); - /* Consider HS200 timing mode */ - if (error == SDMMC_OK && MMC_EXT_EXT_CSD_REV(driver->card.EXT) >= 6 - && MMC_IsCSDVer1_2((&driver->card)) && MMC_EXT_CARD_TYPE(driver->card.EXT) & 0x10 - && HwIsTimingSupported(driver, SDMMC_TIM_MMC_HS200)) - tim_mode = SDMMC_TIM_MMC_HS200; - /* Consider High Speed DDR timing mode */ - else if (error == SDMMC_OK && MMC_EXT_EXT_CSD_REV(driver->card.EXT) >= 4 - && MMC_IsCSDVer1_2((&driver->card)) && MMC_EXT_CARD_TYPE(driver->card.EXT) & 0x4 - && HwIsTimingSupported(driver, SDMMC_TIM_MMC_HS_DDR)) - tim_mode = SDMMC_TIM_MMC_HS_DDR; - /* Consider High Speed SDR timing mode */ - else if (error == SDMMC_OK - && MMC_IsCSDVer1_2((&driver->card)) && MMC_EXT_CARD_TYPE(driver->card.EXT) & 0x1 - && HwIsTimingSupported(driver, SDMMC_TIM_MMC_HS_SDR)) - tim_mode = SDMMC_TIM_MMC_HS_SDR; - /* Check power requirements of the device */ - if (error == SDMMC_OK) { - if (tim_mode == SDMMC_TIM_MMC_HS200) - pwr_class = MMC_EXT_PWR_CL_200_195(driver->card.EXT); - else if (tim_mode == SDMMC_TIM_MMC_HS_DDR) - pwr_class = MMC_EXT_PWR_CL_DDR_52_360(driver->card.EXT); - else if (tim_mode == SDMMC_TIM_MMC_HS_SDR) - pwr_class = MMC_EXT_PWR_CL_52_360(driver->card.EXT); - else - pwr_class = MMC_EXT_PWR_CL_26_360(driver->card.EXT); - - if (pwr_class != 0) { - sw_arg.index = MMC_EXT_POWER_CLASS_I; - sw_arg.value = 0xf; - error = MmcCmd6(driver, &sw_arg, &status); - if (error) { - TRACE_DEBUG_1("Pwr class %s\n\r",SD_StringifyRetCode(error)); - } - } - } - - /* Enable High Speed SDR timing mode */ - if (tim_mode == SDMMC_TIM_MMC_HS_SDR || tim_mode == SDMMC_TIM_MMC_HS_DDR) { - - sw_arg.index = MMC_EXT_HS_TIMING_I; - sw_arg.value = MMC_EXT_HS_TIMING_EN; - - error = MmcCmd6(driver, &sw_arg, &status); - - if (error == SDMMC_OK) - error = HwSetHsMode(driver, SDMMC_TIM_MMC_HS_SDR); - if (error == SDMMC_OK) - error = Cmd13(driver, &status); - if (error == SDMMC_OK && (status & ~STATUS_STATE - & ~STATUS_READY_FOR_DATA - || (status & STATUS_STATE) != STATUS_TRAN)) - error = SDMMC_STATE; - if (error == SDMMC_OK) { - driver->card.bSpeedMode = SDMMC_TIM_MMC_HS_SDR; - freq = SdmmcGetMaxFreq(driver); - error = HwSetClock(driver, &freq); - driver->card.dwCurrSpeed = freq; - error = error == SDMMC_CHANGED ? SDMMC_OK : error; - } - if (error != SDMMC_OK) { - TRACE_ERROR_1("HS %s\n\r", SD_StringifyRetCode(error)); - return error; - } - } - - /* Consider using the widest supported data bus */ - if (MMC_IsCSDVer1_2((&driver->card)) && MMC_IsVer4((&driver->card))) { - - width = mmcDetectBuswidth(driver); - - if (width > 1) { - - error = mmcSelectBuswidth(driver, width,tim_mode == SDMMC_TIM_MMC_HS_DDR); - - if (error == SDMMC_OK) - error = HwSetBusWidth(driver, width); - - if (error == SDMMC_OK) - driver->card.bBusMode = width; - - if (error == SDMMC_OK && tim_mode == SDMMC_TIM_MMC_HS_DDR) - /* Switch to High Speed DDR timing mode */ - error = HwSetHsMode(driver, tim_mode); - if (error == SDMMC_OK) - error = Cmd13(driver, &status); - if (error == SDMMC_OK && (status & ~STATUS_STATE - & ~STATUS_READY_FOR_DATA - || (status & STATUS_STATE) != STATUS_TRAN)) - error = SDMMC_STATE; - if (error == SDMMC_OK - && tim_mode == SDMMC_TIM_MMC_HS_DDR) - driver->card.bSpeedMode = tim_mode; - else if (error) { - TRACE_ERROR_1("Width/DDR %s\n\r",SD_StringifyRetCode(error)); - return error; - } - } - } - - /* Enable HS200 timing mode */ - if (tim_mode == SDMMC_TIM_MMC_HS200 && driver->card.bBusMode > 1) { - sw_arg.index = MMC_EXT_HS_TIMING_I; - /* Select device output Driver Type-0, i.e. 50 ohm nominal - * output impedance. - * TODO select the optimal device output Driver Type. - * That depends on board design. Use an oscilloscope to observe - * signal integrity, and among the driver types that meet rise - * and fall time requirements, select the weakest. */ - sw_arg.value = MMC_EXT_HS_TIMING_HS200 | MMC_EXT_HS_TIMING_50R; - error = MmcCmd6(driver, &sw_arg, &status); - if (error == SDMMC_OK) - error = HwSetHsMode(driver, tim_mode); - if (error == SDMMC_OK) { - error = Cmd13(driver, &status); - if (error == SDMMC_OK && (status & ~STATUS_STATE - & ~STATUS_READY_FOR_DATA - || (status & STATUS_STATE) != STATUS_TRAN)) - error = SDMMC_STATE; - } - if (error == SDMMC_OK) { - driver->card.bSpeedMode = tim_mode; - freq = SdmmcGetMaxFreq(driver); - error = HwSetClock(driver, &freq); - driver->card.dwCurrSpeed = freq; - error = error == SDMMC_CHANGED ? SDMMC_OK : error; - } - if (error != SDMMC_OK) { - TRACE_ERROR_1("HS200 %s\n\r", SD_StringifyRetCode(error)); - return error; - } - } - - /* Update card information since status changed */ - flag = driver->card.bSpeedMode >= SDMMC_TIM_MMC_HS_SDR; - if (flag || driver->card.bBusMode > 1) - SdMmcUpdateInformation(driver, flag, true); - - /* MMC devices have the SET_BLOCK_COUNT command part of both the - * block-oriented read and the block-oriented write commands, - * i.e. class 2 and class 4 commands. - * FIXME we should normally check CSD.CCC before issuing any MMC block- - * oriented read/write command. */ - driver->card.bSetBlkCnt = 1; - /* Ask the driver to implicitly send the SET_BLOCK_COUNT command, - * immediately before every READ_MULTIPLE_BLOCK and WRITE_MULTIPLE_BLOCK - * command. */ - driver->control_param = driver->card.bSetBlkCnt; - drv_err = sdmmc_device_control(driver,SDMMC_IOCTL_SET_LENPREFIX); - - /* In case the driver does not support this function, we'll take it in - * charge. */ - if (driver->card.bSetBlkCnt && drv_err == SDMMC_OK && driver->control_param) - driver->card.bSetBlkCnt = 0; - - driver->card.wCurrBlockLen = SDMMC_BLOCK_SIZE; - - if (MMC_IsCSDVer1_2((&driver->card)) && MMC_IsVer4((&driver->card))) { - /* Get size from EXT_CSD */ - if (MMC_EXT_DATA_SECTOR_SIZE(driver->card.EXT) - == MMC_EXT_DATA_SECT_4KIB) - driver->card.wBlockSize = 4096; - else - driver->card.wBlockSize = 512; - driver->card.dwNbBlocks = MMC_EXT_SEC_COUNT(driver->card.EXT) - / (driver->card.wBlockSize / 512UL); - /* Device density >= 4 GiB does not fit 32-bit dwTotalSize */ - driver->card.dwTotalSize = MMC_EXT_SEC_COUNT(driver->card.EXT); - if (driver->card.dwTotalSize >= 0x800000) - driver->card.dwTotalSize = 0xFFFFFFFF; - else - driver->card.dwTotalSize *= 512UL; - } - else { - driver->card.wBlockSize = 512; - mem_size = SD_CSD_TOTAL_SIZE(driver->card.CSD); - driver->card.dwNbBlocks = (uint32_t)(mem_size >> 9); - driver->card.dwTotalSize = mem_size >> 32 ? 0xFFFFFFFF - : (uint32_t)mem_size; - } - - /* Check device status and eat past exceptions, which would otherwise - * prevent upcoming data transaction routines from reliably checking - * fresh exceptions. */ - error = Cmd13(driver, &status); - if (error) - return error; - status = status & ~STATUS_STATE & ~STATUS_READY_FOR_DATA & ~STATUS_APP_CMD; - if (status) { - TRACE_WARNING_1("st %lx\n\r", status); - } - - return SDMMC_OK; -} -#endif -#endif diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.h deleted file mode 100644 index 573c65059..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CH_SDMMC_MMC_H_ -#define CH_SDMMC_MMC_H_ - -extern uint8_t MmcInit(SdmmcDriver *driver); -extern uint8_t MmcGetExtInformation(SdmmcDriver *driver); - - -#endif /* CH_SDMMC_MMC_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sama5d2.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sama5d2.h deleted file mode 100644 index 8c71753f3..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sama5d2.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef CH_SDMMC_SAMA5D2_H_ -#define CH_SDMMC_SAMA5D2_H_ - - -#define EXT_SIZE 512 -#define SSR_SIZE 64 -#define SCR_SIZE 8 -#define SB1_SIZE 64 -#define SB2_SIZE 8 - -#define SDMMC_BUFFER_SIZE (EXT_SIZE + SSR_SIZE + SCR_SIZE + SB1_SIZE + SB2_SIZE) - -typedef enum -{ - SDMMC_SLOT0 = 0, - SDMMC_SLOT1 -}sdmmcslots_t; - -/* mask for board capabilities defines: voltage, slot type and 8-bit support */ -#define CAPS0_MASK (SDMMC_CA0R_V33VSUP | SDMMC_CA0R_V30VSUP | \ - SDMMC_CA0R_V18VSUP | SDMMC_CA0R_SLTYPE_Msk | \ - SDMMC_CA0R_ED8SUP) -/* SOM1 */ -#if defined(BOARD_ATSAM5D27_SOM1) -#define BOARD_SDMMC0_CAPS0 (SDMMC_CA0R_V33VSUP | \ - SDMMC_CA0R_V18VSUP | \ - SDMMC_CA0R_SLTYPE_REMOVABLECARD | \ - SDMMC_CA0R_ED8SUP) - -#define BOARD_SDMMC1_CAPS0 (SDMMC_CA0R_V33VSUP | \ - SDMMC_CA0R_SLTYPE_REMOVABLECARD) -#elif defined(BOARD_ATSAM5D2_XULT) -#define BOARD_SDMMC0_CAPS0 (SDMMC_CA0R_V33VSUP | \ - SDMMC_CA0R_V18VSUP | \ - SDMMC_CA0R_SLTYPE_EMBEDDED | \ - SDMMC_CA0R_ED8SUP) - -#define BOARD_SDMMC1_CAPS0 (SDMMC_CA0R_V33VSUP | \ - SDMMC_CA0R_SLTYPE_REMOVABLECARD) -#else -#define BOARD_SDMMC0_CAPS0 (SDMMC_CA0R_V33VSUP | \ - SDMMC_CA0R_V18VSUP | \ - SDMMC_CA0R_SLTYPE_EMBEDDED | \ - SDMMC_CA0R_ED8SUP) - -#define BOARD_SDMMC1_CAPS0 (SDMMC_CA0R_V33VSUP | \ - SDMMC_CA0R_SLTYPE_REMOVABLECARD) -#endif - -#endif /* CH_SDMMC_SAMA5D2_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.c b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.c deleted file mode 100644 index 0515cf53a..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.c +++ /dev/null @@ -1,1197 +0,0 @@ -#include -#include "hal.h" - -#if (SAMA_USE_SDMMC == TRUE) -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_cmds.h" -#include "ch_sdmmc_sd.h" -#include "ch_sdmmc_sdio.h" - -static uint8_t PerformSingleTransfer(SdmmcDriver *driver,uint32_t address, uint8_t * pData, uint8_t isRead); -static uint8_t MoveToTransferState(SdmmcDriver *driver,uint32_t address,uint16_t * nbBlocks, uint8_t * pData, uint8_t isRead); -static uint8_t _StopCmd(SdmmcDriver *driver); -static uint8_t _WaitUntilReady(SdmmcDriver *driver, uint32_t last_dev_status); -static uint8_t SdGetTimingFunction(uint8_t mode); -static void SdSelectSlowerTiming(bool high_sig, uint8_t * mode); - -#if SAMA_SDMMC_TRACE == 1 -struct stringEntry_s -{ - const uint8_t key; - const char *name; -}; -const char sdmmcInvalidCode[] = "!Invalid!"; -const struct stringEntry_s sdmmcRCodeNames[] = { - { SDMMC_OK, "OK", }, - { SDMMC_LOCKED, "ERR_LOCKED", }, - { SDMMC_BUSY, "ERR_BUSY", }, - { SDMMC_NO_RESPONSE, "ERR_NO_RESPONSE", }, - { SDMMC_CHANGED, "OK_CHANGED", }, - { SDMMC_ERR, "ERROR", }, - { SDMMC_ERR_IO, "ERR_IO", }, - { SDMMC_ERR_RESP, "ERR_RESP", }, - { SDMMC_NOT_INITIALIZED, "ERR_NOT_INITIALIZED", }, - { SDMMC_PARAM, "ERR_PARAM", }, - { SDMMC_STATE, "ERR_STATE", }, - { SDMMC_USER_CANCEL, "ERR_USER_CANCEL", }, - { SDMMC_NOT_SUPPORTED, "ERR_NO_SUPPORT", }, -}; - -const struct stringEntry_s sdmmcIOCtrlNames[] = { - { SDMMC_IOCTL_BUSY_CHECK, "BUSY_CHECK", }, - { SDMMC_IOCTL_POWER, "POWER", }, - { SDMMC_IOCTL_CANCEL_CMD, "CANCEL_CMD", }, - { SDMMC_IOCTL_RESET, "RESET", }, - { SDMMC_IOCTL_SET_CLOCK, "SET_CLOCK", }, - { SDMMC_IOCTL_SET_BUSMODE, "SET_BUSMODE", }, - { SDMMC_IOCTL_SET_HSMODE, "SET_HSMODE", }, - { SDMMC_IOCTL_SET_BOOTMODE, "SET_BOOTMODE", }, - { SDMMC_IOCTL_SET_LENPREFIX, "SET_LENPREFIX", }, - { SDMMC_IOCTL_GET_CLOCK, "GET_CLOCK", }, - { SDMMC_IOCTL_GET_BUSMODE, "GET_BUSMODE", }, - { SDMMC_IOCTL_GET_HSMODE, "GET_HSMODE", }, - { SDMMC_IOCTL_GET_BOOTMODE, "GET_BOOTMODE", }, - { SDMMC_IOCTL_GET_XFERCOMPL, "GET_XFERCOMPL", }, - { SDMMC_IOCTL_GET_DEVICE, "GET_DEVICE", }, -}; - -const char * SD_StringifyRetCode(uint32_t dwRCode) -{ - const uint8_t bound = ARRAY_SIZE(sdmmcRCodeNames); - uint8_t ix; - - for (ix = 0; ix < bound; ix++) { - if (dwRCode == (uint32_t)sdmmcRCodeNames[ix].key) - return sdmmcRCodeNames[ix].name; - } - - return sdmmcInvalidCode; -} - -const char * SD_StringifyIOCtrl(uint32_t dwCtrl) -{ - const uint8_t bound = ARRAY_SIZE(sdmmcIOCtrlNames); - uint8_t ix; - - for (ix = 0; ix < bound; ix++) { - if (dwCtrl == (uint32_t)sdmmcIOCtrlNames[ix].key) - return sdmmcIOCtrlNames[ix].name; - } - - return sdmmcInvalidCode; -} -#endif - - -/** - * Read Blocks of data in a buffer pointed by pData. The buffer size must be at - * least 512 byte long. This function checks the SD card status register and - * address the card if required before sending the read command. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code". - * \param pSd Pointer to a SD card driver instance. - * \param address Address of the block to read. - * \param pData Data buffer whose size is at least the block size. It shall - * follow the peripheral and DMA alignment requirements. - * \param length Number of blocks to be read. - * \param pCallback Pointer to callback function that invoked when read done. - * 0 to start a blocked read. - * \param pArgs Pointer to callback function arguments. - */ -uint8_t SD_Read(SdmmcDriver *driver,uint32_t address,void *pData, uint32_t length) -{ - uint8_t *out = NULL; - uint32_t remaining, blk_no; - uint16_t limited; - uint8_t error = SDMMC_OK; - - - for (blk_no = address, remaining = length, out = (uint8_t *)pData; - remaining != 0 && error == SDMMC_OK; - blk_no += limited, remaining -= limited, - out += (uint32_t)limited * (uint32_t)driver->card.wCurrBlockLen) - { - limited = (uint16_t)min_u32(remaining, 65535); - error = MoveToTransferState(driver, blk_no, &limited, out, 1); - } - //debug - TRACE_DEBUG_3("SDrd(%lu,%lu) %s\n\r", address, length, SD_StringifyRetCode(error)); - return error; -} - -/** - * Write Blocks of data in a buffer pointed by pData. The buffer size must be at - * least 512 byte long. This function checks the SD card status register and - * address the card if required before sending the read command. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code". - * \param pSd Pointer to a SD card driver instance. - * \param address Address of the block to write. - * \param pData Data buffer whose size is at least the block size. It shall - * follow the peripheral and DMA alignment requirements. - * \param length Number of blocks to be write. - * \param pCallback Pointer to callback function that invoked when write done. - * 0 to start a blocked write. - * \param pArgs Pointer to callback function arguments. - */ -uint8_t SD_Write(SdmmcDriver *driver,uint32_t address,const void *pData,uint32_t length) -{ - uint8_t *in = NULL; - uint32_t remaining, blk_no; - uint16_t limited; - uint8_t error = SDMMC_OK; - -// assert(pSd != NULL); -// assert(pData != NULL); - - for (blk_no = address, remaining = length, in = (uint8_t *)pData; - remaining != 0 && error == SDMMC_OK; - blk_no += limited, remaining -= limited, - in += (uint32_t)limited * (uint32_t)driver->card.wCurrBlockLen) { - limited = (uint16_t)min_u32(remaining, 65535); - error = MoveToTransferState(driver, blk_no, &limited, in, 0); - } - //debug - TRACE_DEBUG_3("SDwr(%lu,%lu) %s\n\r", address, length, SD_StringifyRetCode(error)); - return error; -} - -/** - * Read Blocks of data in a buffer pointed by pData. The buffer size must be at - * least 512 byte long. This function checks the SD card status register and - * address the card if required before sending the read command. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code". - * \param pSd Pointer to a SD card driver instance. - * \param address Address of the block to read. - * \param nbBlocks Number of blocks to be read. - * \param pData Data buffer whose size is at least the block size. It shall - * follow the peripheral and DMA alignment requirements. - */ -uint8_t SD_ReadBlocks(SdmmcDriver *driver, uint32_t address, void *pData, uint32_t nbBlocks) -{ - uint8_t error = 0; - uint8_t *pBytes = (uint8_t *) pData; - - - //debug - TRACE_DEBUG_2("RdBlks(%lu,%lu)\n\r", address, nbBlocks); - - while (nbBlocks--) { - error = PerformSingleTransfer(driver, address, pBytes, 1); - if (error) - break; - address += 1; - pBytes = &pBytes[512]; - } - return error; -} - -/** - * Write Block of data pointed by pData. The buffer size must be at - * least 512 byte long. This function checks the SD card status register and - * address the card if required before sending the read command. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code". - * \param pSd Pointer to a SD card driver instance. - * \param address Address of block to write. - * \param nbBlocks Number of blocks to be read - * \param pData Data buffer whose size is at least the block size. It shall - * follow the peripheral and DMA alignment requirements. - */ -uint8_t SD_WriteBlocks(SdmmcDriver *driver, uint32_t address, const void *pData, uint32_t nbBlocks) -{ - uint8_t error = 0; - uint8_t *pB = (uint8_t *) pData; - - - //debug - TRACE_DEBUG_2("WrBlks(%lu,%lu)\n\r", address, nbBlocks); - - while (nbBlocks--) { - error = PerformSingleTransfer(driver, address, pB, 0); - if (error) - break; - address += 1; - pB = &pB[512]; - } - return error; -} - -uint8_t SD_GetStatus(SdmmcDriver *driver) -{ - uint32_t rc; - - const sSdCard * pSd = &driver->card; - - driver->control_param = 0; - - rc = sdmmc_device_control(driver,SDMMC_IOCTL_GET_DEVICE); - - if (rc != SDMMC_OK || !driver->control_param) - return SDMMC_NOT_SUPPORTED; - - return pSd->bStatus == SDMMC_NOT_SUPPORTED ? SDMMC_ERR : pSd->bStatus; -} - -uint8_t SdDecideBuswidth(SdmmcDriver *drv) -{ - uint8_t error, busWidth = 1; - const uint8_t sd = (drv->card.bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD; - const uint8_t io = (drv->card.bCardType & CARD_TYPE_bmSDIO) != 0; - - if (io) - busWidth = 1; /* SDIO => 1 bit only. TODO: assign CCCR. */ - else if (sd) { - busWidth = 4; /* default to 4-bit mode */ - error = HwSetBusWidth(drv, busWidth); - if (error) - busWidth = 1; - } - /* Switch to selected bus mode */ - if (sd && busWidth > 1) - error = Acmd6(drv, busWidth); - else - error = HwSetBusWidth(drv, busWidth); - if (error) - return error; - drv->card.bBusMode = busWidth; - return 0; -} - - -uint8_t SdEnableHighSpeed(SdmmcDriver *drv) -{ - SdCmd6Arg request = { - .acc_mode = 0xf, - .cmd_sys = 0xf, - .drv_strgth = 0xf, - .pwr_limit = 0xf, - .func_grp5 = 0xf, - .func_grp6 = 0xf, - .set = 0, - }; - uint32_t status; - uint16_t mode_mask, val; - uint8_t mode = drv->card.bCardSigLevel ? SDMMC_TIM_SD_DS : SDMMC_TIM_SD_SDR12; - uint8_t error, mode_func, pwr_func = SD_SWITCH_ST_MAX_PWR_1_44W; - const bool has_io = drv->card.bCardType & CARD_TYPE_bmSDIO ? true : false; - const bool has_mem = drv->card.bCardType & CARD_TYPE_bmSD ? true : false; - const bool has_switch = SD_CSD_CCC(drv->card.CSD) & 1 << 10 ? true : false; - bool sfs_v1 = false; - - //assert(sizeof(pSd->sandbox1) >= 512 / 8); - -#ifndef SDMMC_TRIM_SDIO - /* TODO consider the UHS-I timing modes for SDIO devices too */ - if (has_io && !(has_mem && !has_switch) - && HwIsTimingSupported(drv, SDMMC_TIM_SD_HS)) { - /* Check CIA.HS */ - status = 0; - error = Cmd52(drv, 0, SDIO_CIA, 0, SDIO_HS_REG, &status); - if (error) - return SDMMC_ERR; - if (status & SDIO_SHS) { - /* Enable High Speed timing mode */ - status = SDIO_EHS; - error = Cmd52(drv, 1, SDIO_CIA, 1, SDIO_HS_REG, - &status); - if (error || !(status & SDIO_EHS)) - return SDMMC_ERR; - mode = SDMMC_TIM_SD_HS; - } - } -#endif - - if (!has_mem || !has_switch) - goto Apply; - /* Search for the fastest supported timing mode */ - error = SdCmd6(drv, &request, drv->card.sandbox1, &status); - if (error || status & STATUS_SWITCH_ERROR) - return SDMMC_ERR; - sfs_v1 = SD_SWITCH_ST_DATA_STRUCT_VER(drv->card.sandbox1) >= 0x01; - mode_mask = SD_SWITCH_ST_FUN_GRP1_INFO(drv->card.sandbox1); - TRACE_DEBUG_1("Device timing functions: 0x%04x\n\r", mode_mask); - if (has_io && mode == SDMMC_TIM_SD_HS - && !(mode_mask & 1 << SD_SWITCH_ST_ACC_HS)) - return SDMMC_NOT_SUPPORTED; - else if (has_io) { - /* Have SDMEM use the same timing mode as SDIO */ - } else if (mode_mask & 1 << SD_SWITCH_ST_ACC_SDR104 - && HwIsTimingSupported(drv, SDMMC_TIM_SD_SDR104)) - mode = SDMMC_TIM_SD_SDR104; - else if (mode_mask & 1 << SD_SWITCH_ST_ACC_DDR50 - && HwIsTimingSupported(drv, SDMMC_TIM_SD_DDR50)) - mode = SDMMC_TIM_SD_DDR50; - else if (mode_mask & 1 << SD_SWITCH_ST_ACC_SDR50 - && HwIsTimingSupported(drv, SDMMC_TIM_SD_SDR50)) - mode = SDMMC_TIM_SD_SDR50; - else if (mode_mask & 1 << SD_SWITCH_ST_ACC_HS - && HwIsTimingSupported(drv, SDMMC_TIM_SD_HS)) - mode = SDMMC_TIM_SD_HS; - else - mode = SDMMC_TIM_SD_DS; - /* Verify current signaling level is the one expected by the device */ - if ((mode >= SDMMC_TIM_SD_SDR50 && drv->card.bCardSigLevel != 0) - || (mode < SDMMC_TIM_SD_SDR50 && drv->card.bCardSigLevel == 0)) - return SDMMC_STATE; - /* Check the electrical power requirements of this device */ - val = SD_SWITCH_ST_FUN_GRP4_INFO(drv->card.sandbox1); - TRACE_DEBUG_2("Device pwr & strength functions: 0x%04x & 0x%04x\n\r", val, - SD_SWITCH_ST_FUN_GRP3_INFO(drv->card.sandbox1)); - if (!(val & 1 << SD_SWITCH_ST_MAX_PWR_1_44W)) - pwr_func = SD_SWITCH_ST_MAX_PWR_0_72W; - request.acc_mode = mode_func = SdGetTimingFunction(mode); - request.drv_strgth = SD_SWITCH_ST_OUT_DRV_B; - request.pwr_limit = SD_SWITCH_ST_MAX_PWR_0_72W; - error = SdCmd6(drv, &request, drv->card.sandbox1, &status); - if (error || status & STATUS_SWITCH_ERROR) - return SDMMC_ERR; - val = SD_SWITCH_ST_MAX_CURR_CONSUMPTION(drv->card.sandbox1); - TRACE_DEBUG_1("Device max current: %u mA\n\r", val); - if (val == 0 || val > (1440 * 10) / 36) - SdSelectSlowerTiming(drv->card.bCardSigLevel != 0, &mode); - else if (sfs_v1) { - val = SD_SWITCH_ST_FUN_GRP4_BUSY(drv->card.sandbox1); - if (val & 1 << SD_SWITCH_ST_MAX_PWR_1_44W) - pwr_func = SD_SWITCH_ST_MAX_PWR_0_72W; - val = SD_SWITCH_ST_FUN_GRP1_BUSY(drv->card.sandbox1); - if (val & 1 << mode_func) - SdSelectSlowerTiming(drv->card.bCardSigLevel != 0, &mode); - } - - /* Select device output Driver Type B, i.e. 50 ohm nominal output - * impedance. - * CHTODO: select the optimal device output Driver Type, which depends on - * board design. An oscilloscope should be used to observe signal - * integrity, then among the driver types that meet rise and fall time - * requirements, the weakest should be selected. - */ - request.acc_mode = 0xf; - request.pwr_limit = 0xf; - request.set = 1; - error = SdCmd6(drv, &request, drv->card.sandbox1, &status); - if (error || status & STATUS_SWITCH_ERROR) - return SDMMC_ERR; - val = SD_SWITCH_ST_FUN_GRP3_RC(drv->card.sandbox1); - if (val != request.drv_strgth) - SdSelectSlowerTiming(drv->card.bCardSigLevel != 0, &mode); - -Switch: - /* Now switch the memory device to the candidating mode */ - request.acc_mode = mode_func = SdGetTimingFunction(mode); - request.cmd_sys = 0x0; - request.drv_strgth = 0xf; - request.pwr_limit = pwr_func; - error = SdCmd6(drv, &request, drv->card.sandbox1, &status); - if (error || status & STATUS_SWITCH_ERROR) - return SDMMC_ERR; - val = SD_SWITCH_ST_FUN_GRP1_RC(drv->card.sandbox1); - while (val != mode_func && val != SD_SWITCH_ST_FUN_GRP_RC_ERROR) { - /* CHTODO: break upon timeout condition */ - request.acc_mode = 0xf; - request.cmd_sys = 0xf; - request.pwr_limit = 0xf; - request.set = 0; - error = SdCmd6(drv, &request, drv->card.sandbox1, &status); - if (error || status & STATUS_SWITCH_ERROR) - return SDMMC_ERR; - val = SD_SWITCH_ST_FUN_GRP1_RC(drv->card.sandbox1); - if (val != mode_func && sfs_v1 - && !(SD_SWITCH_ST_FUN_GRP1_BUSY(drv->card.sandbox1) - & 1 << mode_func)) - break; - } - - if (val != mode_func && (mode == SDMMC_TIM_SD_DS || mode == SDMMC_TIM_SD_SDR12)) - return SDMMC_ERR; - else if (val != mode_func) { - SdSelectSlowerTiming(drv->card.bCardSigLevel != 0, &mode); - goto Switch; - } - - val = SD_SWITCH_ST_FUN_GRP4_RC(drv->card.sandbox1); - - if (val != pwr_func) { - TRACE_DEBUG_1("Device power limit 0x%x\n\r", val); - } - -Apply: - error = HwSetHsMode(drv, mode); - if (error == SDMMC_OK) - drv->card.bSpeedMode = mode; - else - return SDMMC_ERR; - return SDMMC_OK; -} - - -void SdGetExtInformation(SdmmcDriver *drv) -{ - uint32_t card_status; - uint8_t error; - - error = Acmd51(drv, drv->card.SCR, &card_status); - - if (error == SDMMC_OK) { - card_status &= ~STATUS_READY_FOR_DATA; - if (card_status != (STATUS_APP_CMD | STATUS_TRAN)) { - TRACE_DEBUG_1("SCR st %lx\n\r", card_status); - } - } - - error = Acmd13(drv, drv->card.SSR, &card_status); - - if (error == SDMMC_OK) { - card_status &= ~STATUS_READY_FOR_DATA; - if (card_status != (STATUS_APP_CMD | STATUS_TRAN)) { - TRACE_DEBUG_1("SSR st %lx\n\r", card_status); - } - } -} - - - -/** - * Reset SD/MMC driver runtime parameters. - */ -void SdParamReset(sSdCard * pSd) -{ - pSd->dwTotalSize = 0; - pSd->dwNbBlocks = 0; - pSd->wBlockSize = 0; - - pSd->wCurrBlockLen = 0; - pSd->dwCurrSpeed = 0; - pSd->wAddress = 0; - - pSd->bCardType = 0; - pSd->bCardSigLevel = 2; - pSd->bSpeedMode = SDMMC_TIM_MMC_BC; - pSd->bBusMode = 1; - pSd->bStatus = SDMMC_NOT_INITIALIZED; - pSd->bSetBlkCnt = 0; - pSd->bStopMultXfer = 0; - - - /* Clear our device register cache */ - memset(pSd->CID, 0, 16); - memset(pSd->CSD, 0, 16); - memset(pSd->EXT, 0, EXT_SIZE); - memset(pSd->SSR, 0, SSR_SIZE); - memset(pSd->SCR, 0, SCR_SIZE); -} - -/** - * Query whether the card is writeprotected or not by mechanical - write protect switch. - * \param pSd Pointer to \ref sSdCard instance. - * \return an \ref sdmmc_rc "error code", as follows: - * - SDMMC_LOCKED if the device has been mechanical write protected. - * - SDMMC_OK if the card is not write-protected. - */ -uint8_t SD_GetWpStatus(SdmmcDriver *driver) -{ - uint32_t rc; - - driver->control_param = 0; - - rc = sdmmc_device_control(driver,SDMMC_IOCTL_GET_WP); - - if (rc != SDMMC_OK) - return SDMMC_NOT_SUPPORTED; - if (!driver->control_param) - return SDMMC_LOCKED; - else - return SDMMC_OK; -} - - -/** - * From a wide-width device register extract the requested field. - * \param reg Contents of the register - * \param reg_len Length of the register, in bits - * \param field_start Offset (address of the least significant bit) of the - * requested field, in bits - * \param field_len Length of the requested field, in bits - * \return The value of the field. - */ -uint32_t SD_GetField(const uint8_t *reg, uint16_t reg_len, uint16_t field_start, - uint8_t field_len) -{ - uint32_t val = 0; - uint8_t byte, expected_bits = field_len, new_bits; - - //assert(reg); - //assert(reg_len % 8 == 0); - //assert(field_len != 0 && field_len <= 32 && field_len <= reg_len); - //assert(field_start <= reg_len - field_len); - - reg += (reg_len - field_start - field_len) / 8; - while (expected_bits) { - byte = *reg; - new_bits = (field_start + expected_bits) % 8; - if (new_bits) - byte &= (1 << new_bits) - 1; - else - new_bits = 8; - if (new_bits <= expected_bits) - val |= (uint32_t)byte << (expected_bits - new_bits); - else { - byte >>= new_bits - expected_bits; - val |= byte; - new_bits = expected_bits; - } - expected_bits -= new_bits; - reg++; - } - //assert((val & ~0 << field_len) == 0); - return val; -} - -static uint8_t SdGetTimingFunction(uint8_t mode) { - if (mode == SDMMC_TIM_SD_SDR104) - return SD_SWITCH_ST_ACC_SDR104; - else if (mode == SDMMC_TIM_SD_DDR50) - return SD_SWITCH_ST_ACC_DDR50; - else if (mode == SDMMC_TIM_SD_SDR50) - return SD_SWITCH_ST_ACC_SDR50; - else if (mode == SDMMC_TIM_SD_HS || mode == SDMMC_TIM_SD_SDR25) - return SD_SWITCH_ST_ACC_HS; - else - return SD_SWITCH_ST_ACC_DS; -} - -static void SdSelectSlowerTiming(bool high_sig, uint8_t * mode) -{ - if (high_sig) - *mode = SDMMC_TIM_SD_DS; - else if (*mode > SDMMC_TIM_SD_SDR50) - *mode = SDMMC_TIM_SD_SDR50; - else if (*mode > SDMMC_TIM_SD_SDR25) - *mode = SDMMC_TIM_SD_SDR25; - else - *mode = SDMMC_TIM_SD_SDR12; -} - -uint32_t SD_GetTotalSizeKB(const sSdCard * pSd) -{ - //assert(pSd != NULL); - - if (pSd->dwTotalSize == 0xFFFFFFFF) - return (pSd->dwNbBlocks / 1024) * pSd->wBlockSize; - else - return pSd->dwTotalSize / 1024; -} - - -void SD_DumpStatus(const sSdCard *pSd) -{ - char text[40] = ""; - char mode[20] = ""; - char vers[7] = { ' ', 'v', '1', '.', '0', '\0', '\0' }; - - //assert(pSd != NULL); - - if (pSd->bCardType & CARD_TYPE_bmHC) - strcat(text, "High-capacity "); - if (pSd->bCardType & CARD_TYPE_bmSDIO - && pSd->bCardType & CARD_TYPE_bmSD) - strcat(text, "SDIO combo card"); - else if (pSd->bCardType & CARD_TYPE_bmSDIO) - strcat(text, "SDIO device"); - else if (pSd->bCardType & CARD_TYPE_bmSD) - strcat(text, "SD card"); -#ifndef SDMMC_TRIM_MMC - else if (pSd->bCardType & CARD_TYPE_bmMMC) - strcat(text, "MMC device"); -#endif - else - strcat(text, "unrecognized device"); - - if (pSd->bCardType & CARD_TYPE_bmMMC) { -#ifndef SDMMC_TRIM_MMC - const uint8_t csd = MMC_CSD_SPEC_VERS(pSd->CSD); - const uint8_t ext = MMC_EXT_EXT_CSD_REV(pSd->EXT); - - if (csd == MMC_CSD_SPEC_VERS_1_4) - vers[4] = '4'; - else if (csd == MMC_CSD_SPEC_VERS_2_0) { - vers[2] = '2'; - vers[4] = 'x'; - } - else if (csd == MMC_CSD_SPEC_VERS_3_1) { - vers[2] = '3'; - vers[4] = 'x'; - } - else if (csd == MMC_CSD_SPEC_VERS_4_0) { - vers[2] = ext <= 6 ? '4' : '5'; - if (ext <= 4) - vers[4] = '0' + ext; - else if (ext == 5) { - vers[4] = '4'; - vers[5] = '1'; - } - else if (ext == 6) { - vers[4] = '5'; - vers[5] = 'x'; - } - else if (ext == 7) - vers[5] = 'x'; - else if (ext == 8) - vers[4] = '1'; - else - vers[4] = 'x'; - } - else if (csd != MMC_CSD_SPEC_VERS_1_0) - vers[2] = vers[4] = '?'; - strcat(text, vers); -#endif - } - else if (pSd->bCardType & CARD_TYPE_bmSD - && SD_SCR_STRUCTURE(pSd->SCR) == SD_SCR_STRUCTURE_1_0) { - if (SD_SCR_SD_SPEC(pSd->SCR) == SD_SCR_SD_SPEC_1_0) - vers[5] = 'x'; - else if (SD_SCR_SD_SPEC(pSd->SCR) == SD_SCR_SD_SPEC_1_10) { - vers[4] = '1'; - vers[5] = '0'; - } - else if (SD_SCR_SD_SPEC(pSd->SCR) == SD_SCR_SD_SPEC_2_00) { - if (SD_SCR_SD_SPEC4(pSd->SCR) == SD_SCR_SD_SPEC_4_X) { - vers[2] = '4'; - vers[4] = vers[5] = 'x'; - } - else if (SD_SCR_SD_SPEC3(pSd->SCR) - == SD_SCR_SD_SPEC_3_0) { - vers[2] = '3'; - vers[5] = 'x'; - } - else { - vers[2] = '2'; - vers[5] = '0'; - } - } - else - vers[2] = vers[4] = '?'; - strcat(text, vers); - } - - if (pSd->bSpeedMode == SDMMC_TIM_MMC_BC) - strcat(mode, "Backward-compatible"); -#ifndef SDMMC_TRIM_MMC - else if (pSd->bSpeedMode == SDMMC_TIM_MMC_HS_SDR) - strcat(mode, "HS SDR"); - else if (pSd->bSpeedMode == SDMMC_TIM_MMC_HS_DDR) - strcat(mode, "HS DDR"); - else if (pSd->bSpeedMode == SDMMC_TIM_MMC_HS200) - strcat(mode, "HS200"); -#endif - else if (pSd->bSpeedMode == SDMMC_TIM_SD_DS) - strcat(mode, "DS"); - else if (pSd->bSpeedMode == SDMMC_TIM_SD_HS) - strcat(mode, "HS"); - else if (pSd->bSpeedMode >= SDMMC_TIM_SD_SDR12 - && pSd->bSpeedMode <= SDMMC_TIM_SD_SDR104) { - char uhs_mode[10] = "UHS-I SDR"; - - if (pSd->bSpeedMode == SDMMC_TIM_SD_DDR50) - uhs_mode[6] = 'D'; - strcat(mode, uhs_mode); - if (pSd->bSpeedMode == SDMMC_TIM_SD_SDR12) - strcat(mode, "12"); - else if (pSd->bSpeedMode == SDMMC_TIM_SD_SDR25) - strcat(mode, "25"); - else if (pSd->bSpeedMode == SDMMC_TIM_SD_SDR50 - || pSd->bSpeedMode == SDMMC_TIM_SD_DDR50) - strcat(mode, "50"); - else - strcat(mode, "104"); - } - - TRACE_DEBUG_4("%s, %u-bit data, in %s mode at %lu kHz\n\r", text, pSd->bBusMode, mode, (pSd->dwCurrSpeed / 1000UL) ); - - if (pSd->bCardType & CARD_TYPE_bmSDMMC) { - TRACE_DEBUG_3("Device memory size: %lu MiB, %lu * %uB\n\r", SD_GetTotalSizeKB(pSd) / 1024ul, pSd->dwNbBlocks,pSd->wBlockSize); - - } - -} - - -/** - * Display the content of the CID register - * \param pSd Pointer to SdCard instance. - */ -void SD_DumpCID(const sSdCard *pSd) -{ - const uint8_t sd_device = (pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD; - - /* Function-only SDIO devices have no CID register */ - if ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmUNKNOWN) - return; - - TRACE("Card IDentification\r\n"); - TRACE_1("MID 0x%02X\r\n", SD_CID_MID(pSd->CID)); - - if (sd_device) { - TRACE_2("OID %c%c\r\n", (char) SD_CID_OID1(pSd->CID),(char) SD_CID_OID0(pSd->CID)); - TRACE_5("PNM %c%c%c%c%c\r\n", (char) SD_CID_PNM4(pSd->CID), - (char) SD_CID_PNM3(pSd->CID), (char) SD_CID_PNM2(pSd->CID), - (char) SD_CID_PNM1(pSd->CID), (char) SD_CID_PNM0(pSd->CID)); - TRACE_2("PRV %u.%u\r\n", SD_CID_PRV1(pSd->CID), - SD_CID_PRV0(pSd->CID)); - TRACE_4("PSN 0x%02X%02X%02X%02X\r\n", SD_CID_PSN3(pSd->CID), - SD_CID_PSN2(pSd->CID), SD_CID_PSN1(pSd->CID), - SD_CID_PSN0(pSd->CID)); - TRACE_2("MDT %u/%02u\r\n", 2000 + SD_CID_MDT_Y(pSd->CID), - SD_CID_MDT_M(pSd->CID)); - } -#ifndef SDMMC_TRIM_MMC - else { - uint16_t year = 1997 + MMC_CID_MDT_Y(pSd->CID); - - if (MMC_EXT_EXT_CSD_REV(pSd->EXT) >= 3) { - TRACE_1("CBX %u\r\n", eMMC_CID_CBX(pSd->CID)); - TRACE_1("OID 0x%02X\r\n", eMMC_CID_OID(pSd->CID)); - } - else { - TRACE_1("OID 0x%04X\r\n", MMC_CID_OID(pSd->CID)); - } - TRACE_6("PNM %c%c%c%c%c%c\r\n", - (char) MMC_CID_PNM5(pSd->CID), - (char) MMC_CID_PNM4(pSd->CID), - (char) MMC_CID_PNM3(pSd->CID), - (char) MMC_CID_PNM2(pSd->CID), - (char) MMC_CID_PNM1(pSd->CID), - (char) MMC_CID_PNM0(pSd->CID)); - TRACE_2("PRV %u.%u\r\n", MMC_CID_PRV1(pSd->CID), - MMC_CID_PRV0(pSd->CID)); - TRACE_4("PSN 0x%02X%02X%02X%02X\r\n", MMC_CID_PSN3(pSd->CID), - MMC_CID_PSN2(pSd->CID), MMC_CID_PSN1(pSd->CID), - MMC_CID_PSN0(pSd->CID)); - if (MMC_EXT_EXT_CSD_REV(pSd->EXT) > 4 && year < 2010) - year = year - 1997 + 2013; - TRACE_2("MDT %u/%02u\r\n", year, MMC_CID_MDT_M(pSd->CID)); - } -#endif - - TRACE_1("CRC 0x%02X\r\n", SD_CID_CRC(pSd->CID)); -} - - -/** - * Display the content of the SCR register - * \param pSCR Pointer to SCR data. - */ -void SD_DumpSCR(const uint8_t *pSCR) -{ - (void)pSCR; - - _PrintTitle("SD Card Configuration"); - _PrintField("SCR_STRUCT 0x%X\r\n", SD_SCR_STRUCTURE(pSCR)); - _PrintField("SD_SPEC 0x%X\r\n", SD_SCR_SD_SPEC(pSCR)); - _PrintField("SD_SPEC3 %u\r\n", SD_SCR_SD_SPEC3(pSCR)); - _PrintField("SD_SPEC4 %u\r\n", SD_SCR_SD_SPEC4(pSCR)); - _PrintField("DATA_ST_AFTER_ER %u\r\n", - SD_SCR_DATA_STAT_AFTER_ERASE(pSCR)); - _PrintField("SD_SEC 0x%X\r\n", SD_SCR_SD_SECURITY(pSCR)); - _PrintField("EX_SEC 0x%X\r\n", SD_SCR_EX_SECURITY(pSCR)); - _PrintField("SD_BUS_WIDTHS 0x%X\r\n", SD_SCR_SD_BUS_WIDTHS(pSCR)); - _PrintField("CMD20 %u\r\n", SD_SCR_CMD20_SUPPORT(pSCR)); - _PrintField("CMD23 %u\r\n", SD_SCR_CMD23_SUPPORT(pSCR)); - _PrintField("CMD48/49 %u\r\n", SD_SCR_CMD48_SUPPORT(pSCR)); - _PrintField("CMD58/59 %u\r\n", SD_SCR_CMD58_SUPPORT(pSCR)); -} - -/** - * Display the content of the SD Status Register - * \param pSSR Pointer to SSR data. - */ -void SD_DumpSSR(const uint8_t *pSSR) -{ - (void)pSSR; - _PrintTitle("SD Status"); - _PrintField("DAT_BUS_WIDTH 0x%X\r\n", SD_SSR_DAT_BUS_WIDTH(pSSR)); - _PrintField("SEC_MODE %u\r\n", SD_SSR_SECURED_MODE(pSSR)); - _PrintField("SD_CARD_TYPE 0x%04X\r\n", SD_SSR_CARD_TYPE(pSSR)); - _PrintField("PAREA_SIZE %lu\r\n", - SD_SSR_SIZE_OF_PROTECTED_AREA(pSSR)); - _PrintField("SPD_CLASS 0x%02X\r\n", SD_SSR_SPEED_CLASS(pSSR)); - _PrintField("UHS_SPD_GRADE 0x%X\r\n", SD_SSR_UHS_SPEED_GRADE(pSSR)); - _PrintField("PE_MOVE %u MB/sec\r\n", SD_SSR_PERFORMANCE_MOVE(pSSR)); - _PrintField("AU_SIZE 0x%X\r\n", SD_SSR_AU_SIZE(pSSR)); - _PrintField("UHS_AU_SIZE 0x%X\r\n", SD_SSR_UHS_AU_SIZE(pSSR)); - _PrintField("ER_SIZE %u AU\r\n", SD_SSR_ERASE_SIZE(pSSR)); - _PrintField("ER_TIMEOUT %u sec\r\n", SD_SSR_ERASE_TIMEOUT(pSSR)); - _PrintField("ER_OFFS %u sec\r\n", SD_SSR_ERASE_OFFSET(pSSR)); -} - - -/** - * Display the content of the CSD register - * \param pSd Pointer to SdCard instance. - */ -void SD_DumpCSD(const sSdCard *pSd) -{ - const uint8_t sd_device = (pSd->bCardType & CARD_TYPE_bmSDMMC) - == CARD_TYPE_bmSD; - const uint8_t sd_csd_v2 = sd_device - && SD_CSD_STRUCTURE(pSd->CSD) >= 0x1; - - _PrintTitle("Card-Specific Data"); - _PrintField("CSD_STRUCT 0x%X\r\n", SD_CSD_STRUCTURE(pSd->CSD)); -#ifndef SDMMC_TRIM_MMC - if (!sd_device) { - _PrintField("SPEC_V 0x%X\r\n", MMC_CSD_SPEC_VERS(pSd->CSD)); - } -#endif - _PrintField("TAAC 0x%X\r\n", SD_CSD_TAAC(pSd->CSD)); - _PrintField("NSAC 0x%X\r\n", SD_CSD_NSAC(pSd->CSD)); - _PrintField("TRAN_SPD 0x%X\r\n", SD_CSD_TRAN_SPEED(pSd->CSD)); - _PrintField("CCC 0x%X\r\n", SD_CSD_CCC(pSd->CSD)); - _PrintField("RD_BL_LEN 0x%X\r\n", SD_CSD_READ_BL_LEN(pSd->CSD)); - _PrintField("RD_BL_PART %u\r\n", SD_CSD_READ_BL_PARTIAL(pSd->CSD)); - _PrintField("WR_BL_MALIGN %u\r\n", SD_CSD_WRITE_BLK_MISALIGN(pSd->CSD)); - _PrintField("RD_BL_MALIGN %u\r\n", SD_CSD_READ_BLK_MISALIGN(pSd->CSD)); - _PrintField("DSR_IMP %u\r\n", SD_CSD_DSR_IMP(pSd->CSD)); - _PrintField("C_SIZE 0x%lX\r\n", sd_csd_v2 ? SD2_CSD_C_SIZE(pSd->CSD) - : SD_CSD_C_SIZE(pSd->CSD)); - if (!sd_csd_v2) { - _PrintField("RD_CUR_MIN 0x%X\r\n", - SD_CSD_VDD_R_CURR_MIN(pSd->CSD)); - _PrintField("RD_CUR_MAX 0x%X\r\n", - SD_CSD_VDD_R_CURR_MAX(pSd->CSD)); - _PrintField("WR_CUR_MIN 0x%X\r\n", - SD_CSD_VDD_W_CURR_MIN(pSd->CSD)); - _PrintField("WR_CUR_MAX 0x%X\r\n", - SD_CSD_VDD_W_CURR_MAX(pSd->CSD)); - _PrintField("C_SIZE_MULT 0x%X\r\n", - SD_CSD_C_SIZE_MULT(pSd->CSD)); - } - if (sd_device) { - _PrintField("ER_BL_EN %u\r\n", SD_CSD_ERASE_BLK_EN(pSd->CSD)); - _PrintField("SECT_SIZE 0x%X\r\n", SD_CSD_SECTOR_SIZE(pSd->CSD)); - } -#ifndef SDMMC_TRIM_MMC - else { - _PrintField("ER_GRP_SIZE 0x%X\r\n", - MMC_CSD_ERASE_GRP_SIZE(pSd->CSD)); - _PrintField("ER_GRP_MULT 0x%X\r\n", - MMC_CSD_ERASE_GRP_MULT(pSd->CSD)); - } -#endif -#ifdef SDMMC_TRIM_MMC - _PrintField("WP_GRP_SIZE 0x%X\r\n", SD_CSD_WP_GRP_SIZE(pSd->CSD)); -#else - _PrintField("WP_GRP_SIZE 0x%X\r\n", sd_device ? - SD_CSD_WP_GRP_SIZE(pSd->CSD) : MMC_CSD_WP_GRP_SIZE(pSd->CSD)); -#endif - _PrintField("WP_GRP_EN %u\r\n", SD_CSD_WP_GRP_ENABLE(pSd->CSD)); -#ifndef SDMMC_TRIM_MMC - if (!sd_device) { - _PrintField("DEF_ECC 0x%X\r\n", MMC_CSD_DEFAULT_ECC(pSd->CSD)); - } -#endif - _PrintField("R2W_FACT 0x%X\r\n", SD_CSD_R2W_FACTOR(pSd->CSD)); - _PrintField("WR_BL_LEN 0x%X\r\n", SD_CSD_WRITE_BL_LEN(pSd->CSD)); - _PrintField("WR_BL_PART %u\r\n", SD_CSD_WRITE_BL_PARTIAL(pSd->CSD)); - _PrintField("FILE_FMT_GRP %u\r\n", SD_CSD_FILE_FORMAT_GRP(pSd->CSD)); - _PrintField("COPY %u\r\n", SD_CSD_COPY(pSd->CSD)); - _PrintField("PERM_WP %u\r\n", SD_CSD_PERM_WRITE_PROTECT(pSd->CSD)); - _PrintField("TMP_WP %u\r\n", SD_CSD_TMP_WRITE_PROTECT(pSd->CSD)); - _PrintField("FILE_FMT 0x%X\r\n", SD_CSD_FILE_FORMAT(pSd->CSD)); -#ifndef SDMMC_TRIM_MMC - if (!sd_device) { - _PrintField("ECC 0x%X\r\n", MMC_CSD_ECC(pSd->CSD)); - } -#endif - _PrintField("CRC 0x%X\r\n", SD_CSD_CRC(pSd->CSD)); -} - -/** - * Display the content of the EXT_CSD register - * \param pExtCSD Pointer to extended CSD data. - */ -void SD_DumpExtCSD(const uint8_t *pExtCSD) -{ - (void)pExtCSD; - _PrintTitle("Extended Device Specific Data"); - _PrintField("S_CMD_SET 0x%X\r\n", MMC_EXT_S_CMD_SET(pExtCSD)); - _PrintField("BOOT_INFO 0x%X\r\n", MMC_EXT_BOOT_INFO(pExtCSD)); - _PrintField("BOOT_SIZE_MULTI 0x%X\r\n", - MMC_EXT_BOOT_SIZE_MULTI(pExtCSD)); - _PrintField("ACC_SIZE 0x%X\r\n", MMC_EXT_ACC_SIZE(pExtCSD)); - _PrintField("HC_ER_GRP_SIZE 0x%X\r\n", - MMC_EXT_HC_ERASE_GRP_SIZE(pExtCSD)); - _PrintField("ER_TIMEOUT_MULT 0x%X\r\n", - MMC_EXT_ERASE_TIMEOUT_MULT(pExtCSD)); - _PrintField("REL_WR_SEC_C 0x%X\r\n", MMC_EXT_REL_WR_SEC_C(pExtCSD)); - _PrintField("HC_WP_GRP_SIZE 0x%X\r\n", MMC_EXT_HC_WP_GRP_SIZE(pExtCSD)); - _PrintField("S_C_VCC 0x%X\r\n", MMC_EXT_S_C_VCC(pExtCSD)); - _PrintField("S_C_VCCQ 0x%X\r\n", MMC_EXT_S_C_VCCQ(pExtCSD)); - _PrintField("S_A_TIMEOUT 0x%X\r\n", MMC_EXT_S_A_TIMEOUT(pExtCSD)); - _PrintField("SEC_CNT 0x%lX\r\n", MMC_EXT_SEC_COUNT(pExtCSD)); - _PrintField("MIN_PE_W_8_52 0x%X\r\n", MMC_EXT_MIN_PERF_W_8_52(pExtCSD)); - _PrintField("MIN_PE_R_8_52 0x%X\r\n", MMC_EXT_MIN_PERF_R_8_52(pExtCSD)); - _PrintField("MIN_PE_W_8_26_4_52 0x%X\r\n", - MMC_EXT_MIN_PERF_W_8_26_4_52(pExtCSD)); - _PrintField("MIN_PE_R_8_26_4_52 0x%X\r\n", - MMC_EXT_MIN_PERF_R_8_26_4_52(pExtCSD)); - _PrintField("MIN_PE_W_4_26 0x%X\r\n", MMC_EXT_MIN_PERF_W_4_26(pExtCSD)); - _PrintField("MIN_PE_R_4_26 0x%X\r\n", MMC_EXT_MIN_PERF_R_4_26(pExtCSD)); - _PrintField("PWR_CL_26_360 0x%X\r\n", MMC_EXT_PWR_CL_26_360(pExtCSD)); - _PrintField("PWR_CL_52_360 0x%X\r\n", MMC_EXT_PWR_CL_52_360(pExtCSD)); - _PrintField("PWR_CL_26_195 0x%X\r\n", MMC_EXT_PWR_CL_26_195(pExtCSD)); - _PrintField("PWR_CL_52_195 0x%X\r\n", MMC_EXT_PWR_CL_52_195(pExtCSD)); - _PrintField("DRV_STR 0x%X\r\n", MMC_EXT_DRV_STRENGTH(pExtCSD)); - _PrintField("CARD_TYPE 0x%X\r\n", MMC_EXT_CARD_TYPE(pExtCSD)); - _PrintField("CSD_STRUCT 0x%X\r\n", MMC_EXT_CSD_STRUCTURE(pExtCSD)); - _PrintField("EXT_CSD_REV 0x%X\r\n", MMC_EXT_EXT_CSD_REV(pExtCSD)); - _PrintField("CMD_SET 0x%X\r\n", MMC_EXT_CMD_SET(pExtCSD)); - _PrintField("CMD_SET_REV 0x%X\r\n", MMC_EXT_CMD_SET_REV(pExtCSD)); - _PrintField("PWR_CLASS 0x%X\r\n", MMC_EXT_POWER_CLASS(pExtCSD)); - _PrintField("HS_TIM 0x%X\r\n", MMC_EXT_HS_TIMING(pExtCSD)); - _PrintField("BUS_WIDTH 0x%X\r\n", MMC_EXT_BUS_WIDTH(pExtCSD)); - _PrintField("ER_MEM_CONT 0x%X\r\n", MMC_EXT_ERASED_MEM_CONT(pExtCSD)); - _PrintField("BOOT_CFG 0x%X\r\n", MMC_EXT_BOOT_CONFIG(pExtCSD)); - _PrintField("BOOT_BUS_WIDTH 0x%X\r\n", MMC_EXT_BOOT_BUS_WIDTH(pExtCSD)); - _PrintField("ER_GRP_DEF 0x%X\r\n", MMC_EXT_ERASE_GROUP_DEF(pExtCSD)); -} - - - -/** - * Transfer a single data block. - * The device shall be in its Transfer State already. - * \param pSd Pointer to a SD card driver instance. - * \param address Address of the block to transfer. - * \param pData Data buffer, whose size is at least one block size. - * \param isRead Either 1 to read data from the device or 0 to write data. - * \return a \ref sdmmc_rc result code. - */ -static uint8_t PerformSingleTransfer(SdmmcDriver *driver,uint32_t address, uint8_t * pData, uint8_t isRead) -{ - uint8_t result = SDMMC_OK, error; - uint32_t sdmmc_address, status; - - /* Convert block address into device-expected unit */ - if (driver->card.bCardType & CARD_TYPE_bmHC) - sdmmc_address = address; - else if (address <= 0xfffffffful / driver->card.wCurrBlockLen) - sdmmc_address = address * driver->card.wCurrBlockLen; - else - return SDMMC_PARAM; - - if (isRead) - /* Read a single data block */ - error = Cmd17(driver, pData, sdmmc_address, &status); - else - /* Write a single data block */ - error = Cmd24(driver, pData, sdmmc_address, &status); - - if (!error) { - status = status & (isRead ? STATUS_READ : STATUS_WRITE) - & ~STATUS_READY_FOR_DATA & ~STATUS_STATE; - if (status) { - //error - TRACE_1("st %lx\n\r", status); - error = SDMMC_ERR; - } - } - if (error) { - //error - TRACE_ERROR_3("Cmd%u(0x%lx) %s\n\r", isRead ? 17 : 24,sdmmc_address, SD_StringifyRetCode(error)); - result = error; - error = Cmd13(driver, &status); - if (error) { - driver->card.bStatus = error; - return result; - } - error = _WaitUntilReady(driver, status); - if (error) { - driver->card.bStatus = error; - return result; - } - } - return result; -} - -/** - * Move SD card to transfer state. The buffer size must be at - * least 512 byte long. This function checks the SD card status register and - * address the card if required before sending the transfer command. - * Returns 0 if successful; otherwise returns an code describing the error. - * \param pSd Pointer to a SD card driver instance. - * \param address Address of the block to transfer. - * \param nbBlocks Pointer to count of blocks to transfer. Pointer to 0 - * for infinite transfer. Upon return, points to the count of blocks actually - * transferred. - * \param pData Data buffer whose size is at least the block size. - * \param isRead 1 for read data and 0 for write data. - */ -static uint8_t MoveToTransferState(SdmmcDriver *driver,uint32_t address,uint16_t * nbBlocks, uint8_t * pData, uint8_t isRead) -{ - uint8_t result = SDMMC_OK, error; - uint32_t sdmmc_address, state, status; - - /* Convert block address into device-expected unit */ - if (driver->card.bCardType & CARD_TYPE_bmHC) - sdmmc_address = address; - else if (address <= 0xfffffffful / driver->card.wCurrBlockLen) - sdmmc_address = address * driver->card.wCurrBlockLen; - else - return SDMMC_PARAM; - - if (driver->card.bSetBlkCnt) { - error = Cmd23(driver, 0, *nbBlocks, &status); - if (error) - return error; - } - - if (isRead) - /* Move to Receiving data state */ - error = Cmd18(driver, nbBlocks, pData, sdmmc_address, &status); - else - /* Move to Sending data state */ - error = Cmd25(driver, nbBlocks, pData, sdmmc_address, &status); - - if (error == SDMMC_CHANGED) - error = SDMMC_OK; - - if (!error) { - status = status & (isRead ? STATUS_READ : STATUS_WRITE) - & ~STATUS_READY_FOR_DATA & ~STATUS_STATE; - - if (driver->card.bStopMultXfer) - error = _StopCmd(driver); - - if (status) { - //error - TRACE_DEBUG_1("st %lx\n\r", status); - /* TODO ignore STATUS_ADDR_OUT_OR_RANGE if the read - * operation is for the last block of memory area. */ - error = SDMMC_ERR; - } - /* CHTODO: when not using the STOP_TRANSMISSION command (using the - * SET_BLOCK_COUNT command instead), we should issue the - * SEND_STATUS command, eat and handle any Execution Mode - * exception. */ - } - if (error) { - //error - TRACE_ERROR_4("Cmd%u(0x%lx, %u) %s\n\r", isRead ? 18 : 25,sdmmc_address, *nbBlocks, SD_StringifyRetCode(error)); - result = error; - error = Cmd13(driver, &status); - - if (error) { - driver->card.bStatus = error; - return result; - } - - state = status & STATUS_STATE; - - if (state == STATUS_DATA || state == STATUS_RCV) { - - error = Cmd12(driver, &status); - - if (error == SDMMC_OK) { - //info - TRACE_INFO_1("st %lx\n\r", status); - - if (status & (STATUS_ERASE_SEQ_ERROR - | STATUS_ERASE_PARAM | STATUS_UN_LOCK_FAILED - | STATUS_ILLEGAL_COMMAND - | STATUS_CIDCSD_OVERWRITE - | STATUS_ERASE_RESET | STATUS_SWITCH_ERROR)) - result = SDMMC_STATE; - else if (status & (STATUS_COM_CRC_ERROR - | STATUS_CARD_ECC_FAILED | STATUS_ERROR)) - result = SDMMC_ERR_IO; - else if (status & (STATUS_ADDR_OUT_OR_RANGE - | STATUS_ADDRESS_MISALIGN - | STATUS_BLOCK_LEN_ERROR - | STATUS_WP_VIOLATION - | STATUS_WP_ERASE_SKIP)) - result = SDMMC_PARAM; - else if (status & STATUS_CC_ERROR) - result = SDMMC_ERR; - } - else if (error == SDMMC_NO_RESPONSE) - error = Cmd13(driver, &status); - if (error) { - driver->card.bStatus = error; - return result; - } - } - error = _WaitUntilReady(driver, status); - - if (error) { - driver->card.bStatus = error; - return result; - } - } - return result; -} - -/** - * Stop TX/RX - */ -static uint8_t _StopCmd(SdmmcDriver *driver) -{ - uint32_t status, state = STATUS_RCV; - uint32_t i; - uint8_t err, count; - /* When stopping a write operation, allow retrying several times */ - for (i = 0; i < 9 && state == STATUS_RCV; i++) { - err = Cmd12(driver, &status); - if (err) - return err; - /* TODO handle any exception, raised in status; report that - * the data transfer has failed. */ - - /* Wait until ready. Allow 30 ms. */ - for (count = 0; count < 6; count++) { - /* Wait for about 5 ms - which equals 5 system ticks */ - t_msleep(driver,5); - err = Cmd13(driver, &status); - if (err) - return err; - state = status & STATUS_STATE; - - /* Invalid state */ - if (state == STATUS_IDLE || state == STATUS_READY - || state == STATUS_IDENT || state == STATUS_STBY - || state == STATUS_DIS) - return SDMMC_NOT_INITIALIZED; - - /* Ready? */ - if ((status & STATUS_READY_FOR_DATA) == - STATUS_READY_FOR_DATA && state == STATUS_TRAN) - return SDMMC_OK; - } - } - return SDMMC_STATE; -} - -static uint8_t _WaitUntilReady(SdmmcDriver *driver, uint32_t last_dev_status) -{ - uint32_t state, status = last_dev_status; - uint8_t err, count; - - for (count = 0; count < 51; count++) { - state = status & STATUS_STATE; - if (state == STATUS_TRAN && status & STATUS_READY_FOR_DATA) - return SDMMC_OK; - /* Sending-data and Receive-data states may be encountered - * temporarily further to single-block data transfers. */ - /* CHTODO: state 15 "reserved for I/O mode" may be allowed */ - if (state != STATUS_TRAN && state != STATUS_PRG - && state != STATUS_DATA && state != STATUS_RCV) - return SDMMC_NOT_INITIALIZED; - /* Wait for about 10 ms - which equals 10 system ticks */ - t_msleep(driver,10); - err = Cmd13(driver, &status); - if (err) - return err; - } - return SDMMC_BUSY; -} - -#endif diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.h deleted file mode 100644 index b9d6a6ccc..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef CH_SDMMC_SD_H_ -#define CH_SDMMC_SD_H_ - - -/** \addtogroup sd_scr_acc SD SCR register fields - * @{ - */ -/** SCR (Configuration register) access macros (64 bits, 2 * 32 bits, 8 * 8 bits). */ -#define SD_SCR(pScr, field, bits) SD_GetField(pScr, 64, field, bits) -#define SD_SCR_STRUCTURE(pScr) (uint8_t)SD_SCR(pScr, 60, 4) -#define SD_SCR_STRUCTURE_1_0 0 /**< SD v1.01~3.01 */ -#define SD_SCR_SD_SPEC(pScr) (uint8_t)SD_SCR(pScr, 56, 4) -#define SD_SCR_SD_SPEC_1_0 0 /**< SD v1.0~1.01 */ -#define SD_SCR_SD_SPEC_1_10 1 /**< SD v1.10 */ -#define SD_SCR_SD_SPEC_2_00 2 /**< SD v2.00 */ -#define SD_SCR_DATA_STAT_AFTER_ERASE(pScr) (uint8_t)SD_SCR(pScr, 55, 1) -#define SD_SCR_SD_SECURITY(pScr) (uint8_t)SD_SCR(pScr, 52, 3) -#define SD_SCR_SD_SECURITY_NO 0 /**< No security */ -#define SD_SCR_SD_SECURITY_NOTUSED 1 /**< Not used */ -#define SD_SCR_SD_SECURITY_1_01 2 /**< Version 1.01 */ -#define SD_SCR_SD_SECURITY_2_00 3 /**< Version 2.00 */ -#define SD_SCR_SD_BUS_WIDTHS(pScr) (uint8_t)SD_SCR(pScr, 48, 4) -#define SD_SCR_SD_BUS_WIDTH_1BITS (1 << 0) /**< 1 bit (DAT0) */ -#define SD_SCR_SD_BUS_WIDTH_4BITS (1 << 2) /**< 4 bit (DAT0~3) */ -#define SD_SCR_SD_SPEC3(pScr) (uint8_t)SD_SCR(pScr, 47, 1) -#define SD_SCR_SD_SPEC_3_0 1 /**< SD v3.0X */ -#define SD_SCR_EX_SECURITY(pScr) (uint8_t)SD_SCR(pScr, 43, 4) -#define SD_SCR_EX_SECURITY_NO 0 /**< No extended security */ -#define SD_SCR_SD_SPEC4(pScr) (uint8_t)SD_SCR(pScr, 42, 1) -#define SD_SCR_SD_SPEC_4_X 1 /**< SD v4.XX */ -#define SD_SCR_CMD58_SUPPORT(pScr) (uint8_t)SD_SCR(pScr, 35, 1) -#define SD_SCR_CMD48_SUPPORT(pScr) (uint8_t)SD_SCR(pScr, 34, 1) -#define SD_SCR_CMD23_SUPPORT(pScr) (uint8_t)SD_SCR(pScr, 33, 1) -#define SD_SCR_CMD20_SUPPORT(pScr) (uint8_t)SD_SCR(pScr, 32, 1) -/** \addtogroup sd_switch_status SD Switch Status fields - * @{ - */ -/** SD Switch Status access macros (512 bits, 16 * 32 bits, 64 * 8 bits). */ -#define SD_SWITCH_ST(p, field, bits) SD_GetField(p, 512, field, bits) -#define SD_SWITCH_ST_MAX_CURR_CONSUMPTION(p) (uint16_t)SD_SWITCH_ST(p, 496, 16) -#define SD_SWITCH_ST_FUN_GRP6_INFO(p) (uint16_t)SD_SWITCH_ST(p, 480, 16) -#define SD_SWITCH_ST_FUN_GRP5_INFO(p) (uint16_t)SD_SWITCH_ST(p, 464, 16) -#define SD_SWITCH_ST_FUN_GRP4_INFO(p) (uint16_t)SD_SWITCH_ST(p, 448, 16) -#define SD_SWITCH_ST_MAX_PWR_0_72W 0x0 -#define SD_SWITCH_ST_MAX_PWR_1_44W 0x1 -#define SD_SWITCH_ST_MAX_PWR_2_16W 0x2 -#define SD_SWITCH_ST_MAX_PWR_2_88W 0x3 -#define SD_SWITCH_ST_MAX_PWR_1_80W 0x4 -#define SD_SWITCH_ST_FUN_GRP3_INFO(p) (uint16_t)SD_SWITCH_ST(p, 432, 16) -#define SD_SWITCH_ST_OUT_DRV_B 0x0 -#define SD_SWITCH_ST_OUT_DRV_A 0x1 -#define SD_SWITCH_ST_OUT_DRV_C 0x2 -#define SD_SWITCH_ST_OUT_DRV_D 0x3 -#define SD_SWITCH_ST_FUN_GRP2_INFO(p) (uint16_t)SD_SWITCH_ST(p, 416, 16) -#define SD_SWITCH_ST_FUN_GRP1_INFO(p) (uint16_t)SD_SWITCH_ST(p, 400, 16) -#define SD_SWITCH_ST_ACC_DS 0x0 -#define SD_SWITCH_ST_ACC_HS 0x1 -#define SD_SWITCH_ST_ACC_SDR50 0x2 -#define SD_SWITCH_ST_ACC_SDR104 0x3 -#define SD_SWITCH_ST_ACC_DDR50 0x4 -#define SD_SWITCH_ST_FUN_GRP6_RC(p) (uint8_t) SD_SWITCH_ST(p, 396, 4) -#define SD_SWITCH_ST_FUN_GRP5_RC(p) (uint8_t) SD_SWITCH_ST(p, 392, 4) -#define SD_SWITCH_ST_FUN_GRP4_RC(p) (uint8_t) SD_SWITCH_ST(p, 388, 4) -#define SD_SWITCH_ST_FUN_GRP3_RC(p) (uint8_t) SD_SWITCH_ST(p, 384, 4) -#define SD_SWITCH_ST_FUN_GRP2_RC(p) (uint8_t) SD_SWITCH_ST(p, 380, 4) -#define SD_SWITCH_ST_FUN_GRP1_RC(p) (uint8_t) SD_SWITCH_ST(p, 376, 4) -#define SD_SWITCH_ST_FUN_GRP_RC_ERROR 0xF -#define SD_SWITCH_ST_DATA_STRUCT_VER(p) (uint8_t) SD_SWITCH_ST(p, 368, 8) -#define SD_SWITCH_ST_FUN_GRP6_BUSY(p) (uint16_t)SD_SWITCH_ST(p, 352, 16) -#define SD_SWITCH_ST_FUN_GRP5_BUSY(p) (uint16_t)SD_SWITCH_ST(p, 336, 16) -#define SD_SWITCH_ST_FUN_GRP4_BUSY(p) (uint16_t)SD_SWITCH_ST(p, 320, 16) -#define SD_SWITCH_ST_FUN_GRP3_BUSY(p) (uint16_t)SD_SWITCH_ST(p, 304, 16) -#define SD_SWITCH_ST_FUN_GRP2_BUSY(p) (uint16_t)SD_SWITCH_ST(p, 288, 16) -#define SD_SWITCH_ST_FUN_GRP1_BUSY(p) (uint16_t)SD_SWITCH_ST(p, 272, 16) -#define SD_SWITCH_ST_FUN_GRP_FUN_BUSY(funNdx) (1 << (funNdx)) -/** @}*/ - -/** We support 2.7 ~ 3.3V cards */ -#define SD_HOST_VOLTAGE_RANGE (SD_OCR_VDD_27_28 +\ - SD_OCR_VDD_28_29 +\ - SD_OCR_VDD_29_30 +\ - SD_OCR_VDD_30_31 +\ - SD_OCR_VDD_31_32 +\ - SD_OCR_VDD_32_33 +\ - SD_OCR_VDD_33_34 +\ - SD_OCR_VDD_34_35 +\ - SD_OCR_VDD_35_36 ) - - - -/** @}*/ - -extern uint8_t SD_GetStatus(SdmmcDriver *driver); -extern uint8_t SdDecideBuswidth(SdmmcDriver *drv); -extern uint8_t SdEnableHighSpeed(SdmmcDriver *drv); -extern uint32_t SD_GetField(const uint8_t *reg, uint16_t reg_len, uint16_t field_start, - uint8_t field_len); -extern void SdGetExtInformation(SdmmcDriver *drv); - -extern void SD_DumpStatus(const sSdCard *pSd); -extern void SD_DumpCID(const sSdCard *pSd); -extern void SD_DumpSCR(const uint8_t *pSCR); -extern void SD_DumpCSD(const sSdCard *pSd); -extern void SD_DumpExtCSD(const uint8_t *pExtCSD); -extern void SD_DumpSSR(const uint8_t *pSSR); - -extern const char * SD_StringifyRetCode(uint32_t dwRCode); -extern const char * SD_StringifyIOCtrl(uint32_t dwCtrl); - -extern uint8_t SD_Read(SdmmcDriver *driver,uint32_t address,void *pData, uint32_t length); -extern uint8_t SD_Write(SdmmcDriver *driver,uint32_t address,const void *pData,uint32_t length); -extern uint8_t SD_ReadBlocks(SdmmcDriver *driver, uint32_t address, void *pData, uint32_t nbBlocks); -extern uint8_t SD_WriteBlocks(SdmmcDriver *driver, uint32_t address, const void *pData, uint32_t nbBlocks); -extern uint8_t SD_ReadBlocks(SdmmcDriver *driver, uint32_t address, void *pData, uint32_t nbBlocks); -extern uint8_t SD_GetWpStatus(SdmmcDriver *driver); - -#endif /* CH_SDMMC_SD_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.c b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.c deleted file mode 100644 index a7cd77a15..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.c +++ /dev/null @@ -1,293 +0,0 @@ -#include "hal.h" - -#if (SAMA_USE_SDMMC == TRUE) - -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_sdio.h" -#include "ch_sdmmc_cmds.h" -#include "ch_sdmmc_sd.h" - -#ifndef SDMMC_TRIM_SDIO - - - - - -uint8_t SdioInit(SdmmcDriver *driver) -{ - uint32_t freq; - uint8_t error; - - driver->card.bSpeedMode = SDMMC_TIM_SD_DS; - - HwSetHsMode(driver, driver->card.bSpeedMode); - /* Thereafter, the host issues CMD3 (SEND_RELATIVE_ADDR) asks the - * card to publish a new relative card address (RCA), which is shorter than - * CID and which is used to address the card in the future data transfer - * mode. Once the RCA is received the card state changes to the Stand-by - * State. At this point, if the host wants to assign another RCA number, it - * can ask the card to publish a new number by sending another CMD3 command - * to the card. The last published RCA is the actual RCA number of the - * card. */ - error = Cmd3(driver); - - if (error) - return error; - - TRACE_1("RCA=%u\n\r", driver->card.wAddress); - - /* Now select the card, to TRAN state */ - error = SdMmcSelect(driver,driver->card.wAddress, 0); - if (error) - return error; - - /* Enable more bus width Mode */ - error = SdDecideBuswidth(driver); - if (error) { - TRACE_1("Bus width %s\n\r", SD_StringifyRetCode(error)); - return SDMMC_ERR; - } - - /* Consider High-Speed timing mode */ - error = SdEnableHighSpeed(driver); - if (error) - return error; - - /* Increase device clock frequency */ - freq = SdioGetMaxFreq(driver); - - error = HwSetClock(driver, &freq); - driver->card.dwCurrSpeed = freq; - if (error != SDMMC_OK && error != SDMMC_CHANGED) { - TRACE_1("clk %s\n\r", SD_StringifyRetCode(error)); - return error; - } - - return SDMMC_OK; -} - - - -/** - * Read one or more bytes from SDIO card, using RW_DIRECT command. - * \param pSd Pointer to SdCard instance. - * \param functionNum Function number. - * \param address First register address to read from. - * \param pData Pointer to data buffer. - * \param size Buffer size, number of bytes to read. - * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code". - */ -uint8_t SDIO_ReadDirect(SdmmcDriver *sdmmcp, - uint8_t functionNum, - uint32_t address, uint8_t * pData, uint32_t size) -{ - uint8_t error; - uint32_t status; - - sSdCard *pSd = &sdmmcp->card; - - if (pSd->bCardType & CARD_TYPE_bmSDIO) { - if (size == 0) - return SDMMC_PARAM; - while (size--) { - status = 0; - error = - Cmd52(sdmmcp, 0, functionNum, 0, address++, &status); - if (pData) - *pData++ = (uint8_t) status; - if (error || status & STATUS_SDIO_R5) { - //trace_error("IOrdRegs %luB@%lu %s st %lx\n\r", - // size, address, SD_StringifyRetCode(error), - // status); - return SDMMC_ERR; - } - } - } else { - return SDMMC_NOT_SUPPORTED; - } - return 0; -} - - - -/** - * Find SDIO ManfID, Fun0 tuple. - * \param pSd Pointer to \ref sSdCard instance. - * \param address Search area start address. - * \param size Search area size. - * \param pAddrManfID Pointer to ManfID address value buffer. - * \param pAddrFunc0 Pointer to Func0 address value buffer. - */ -uint8_t SdioFindTuples(SdmmcDriver *sdmmcp, - uint32_t address, uint32_t size, - uint32_t * pAddrManfID, uint32_t * pAddrFunc0) -{ - uint8_t error, tmp[3]; - uint32_t addr = address; - uint8_t flagFound = 0; /* 1:Manf, 2:Func0 */ - uint32_t addManfID = 0, addFunc0 = 0; - for (; flagFound != 3;) { - error = SDIO_ReadDirect(sdmmcp, SDIO_CIA, addr, tmp, 3); - if (error) - return error; - /* End */ - if (tmp[0] == CISTPL_END) - break; - /* ManfID */ - else if (tmp[0] == CISTPL_MANFID) { - flagFound |= 1; - addManfID = addr; - } - /* Func0 */ - else if (tmp[0] == CISTPL_FUNCE && tmp[2] == 0x00) { - flagFound |= 2; - addFunc0 = addr; - } - /* Tuple error ? */ - if (tmp[1] == 0) - break; - /* Next address */ - addr += (tmp[1] + 2); - if (addr > (address + size)) - break; - } - if (pAddrManfID) - *pAddrManfID = addManfID; - if (pAddrFunc0) - *pAddrFunc0 = addFunc0; - return 0; -} - - -uint32_t SdioGetMaxFreq(SdmmcDriver *sdmmcp) -{ - uint8_t error; - uint32_t addr = 0, rate; - uint8_t buf[6]; - - /* Check Func0 tuple in CIS area */ - error = SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_CIS_PTR_REG,(uint8_t *)&addr, 3); - - if (error) - return 0; - - error = SdioFindTuples(sdmmcp, addr, 256, NULL, &addr); - - if (error || !addr) - return 0; - - /* Fun0 tuple: fn0_blk_siz & max_tran_speed */ - error = SDIO_ReadDirect(sdmmcp, SDIO_CIA, addr, buf, 6); - - if (error) - return 0; - - rate = SdmmcDecodeTransSpeed(buf[5], sdmmcTransUnits, - sdTransMultipliers); - - if (sdmmcp->card.bSpeedMode == SDMMC_TIM_SD_SDR104 && rate == 200000ul) - rate = 208000ul; - else if (sdmmcp->card.bSpeedMode == SDMMC_TIM_SD_DDR50) - rate /= 2ul; - else if (sdmmcp->card.bSpeedMode == SDMMC_TIM_SD_HS && rate == 25000ul) - rate *= 2ul; - - return rate * 1000ul; -} - -/** - * Display SDIO card informations (CIS, tuple ...) - * \param pSd Pointer to \ref sSdCard instance. - */ -void SDIO_DumpCardInformation(SdmmcDriver *sdmmcp) -{ - uint32_t tmp = 0, addrCIS = 0, addrManfID = 0, addrFuncE = 0; - uint8_t *p = (uint8_t *) & tmp; - uint8_t buf[16]; - - /* CCCR */ - _PrintTitle("CCCR"); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_CCCR_REG, p, 1); - _PrintField("SDIO 0x%02lX", (tmp & SDIO_SDIO) >> 4); - _PrintField("CCCR 0x%02lX", (tmp & SDIO_CCCR) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_SD_REV_REG, p, 1); - _PrintField("SD 0x%02lX", (tmp & SDIO_SD) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_IOE_REG, p, 1); - _PrintField("IOE 0x%02lX", (tmp & SDIO_IOE) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_IOR_REG, p, 1); - _PrintField("IOR 0x%02lX", (tmp & SDIO_IOR) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_IEN_REG, p, 1); - _PrintField("IEN 0x%02lX", (tmp & SDIO_IEN) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_INT_REG, p, 1); - _PrintField("INT %lu", (tmp & SDIO_INT) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_BUS_CTRL_REG, p, 1); - _PrintField("CD 0x%lX", (tmp & SDIO_CD) >> 7); - _PrintField("SCSI 0x%lX", (tmp & SDIO_SCSI) >> 6); - _PrintField("ECSI 0x%lX", (tmp & SDIO_ECSI) >> 5); - _PrintField("BUS_WIDTH 0x%lX", (tmp & SDIO_BUSWIDTH) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_CAP_REG, p, 1); - _PrintField("4BLS 0x%lX", (tmp & SDIO_4BLS) >> 7); - _PrintField("LSC 0x%lX", (tmp & SDIO_LSC) >> 6); - _PrintField("E4MI 0x%lX", (tmp & SDIO_E4MI) >> 5); - _PrintField("S4MI 0x%lX", (tmp & SDIO_S4MI) >> 4); - _PrintField("SBS 0x%lX", (tmp & SDIO_SBS) >> 3); - _PrintField("SRW 0x%lX", (tmp & SDIO_SRW) >> 2); - _PrintField("SMB 0x%lX", (tmp & SDIO_SMB) >> 1); - _PrintField("SDC 0x%lX", (tmp & SDIO_SDC) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_CIS_PTR_REG, p, 3); - _PrintField("CIS_PTR 0x%06lX", tmp); - addrCIS = tmp; - tmp = 0; - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_BUS_SUSP_REG, p, 1); - _PrintField("BR 0x%lX", (tmp & SDIO_BR) >> 1); - _PrintField("BS 0x%lX", (tmp & SDIO_BS) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_FUN_SEL_REG, p, 1); - _PrintField("DF 0x%lX", (tmp & SDIO_DF) >> 7); - _PrintField("FS 0x%lX", (tmp & SDIO_FS) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_EXEC_REG, p, 1); - _PrintField("EX 0x%lX", (tmp & SDIO_EX) >> 0); - _PrintField("EXM 0x%lX", (tmp & SDIO_EXM) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_READY_REG, p, 1); - _PrintField("RF 0x%lX", (tmp & SDIO_RF) >> 1); - _PrintField("RFM 0x%lX", (tmp & SDIO_RFM) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_FN0_BLKSIZ_REG, p, 2); - _PrintField("FN0_SIZE %lu", tmp); - tmp = 0; - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_POWER_REG, p, 1); - _PrintField("EMPC 0x%lX", (tmp & SDIO_EMPC) >> 1); - _PrintField("SMPC 0x%lX", (tmp & SDIO_SMPC) >> 0); - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_HS_REG, p, 1); - _PrintField("EHS 0x%lX", (tmp & SDIO_EHS) >> 1); - _PrintField("SHS 0x%lX", (tmp & SDIO_SHS) >> 0); - /* Metaformat */ - SdioFindTuples(sdmmcp, addrCIS, 128, &addrManfID, &addrFuncE); - if (addrManfID != 0) { - SDIO_ReadDirect(sdmmcp, SDIO_CIA, addrManfID, buf, 6); - _PrintTitle("CISTPL_MANFID"); - _PrintField("MANF 0x%04X", (uint16_t)buf[3] << 8 | buf[2]); - _PrintField("CARD 0x%04X", (uint16_t)buf[5] << 8 | buf[4]); - } - if (addrFuncE != 0) { - SDIO_ReadDirect(sdmmcp, SDIO_CIA, addrFuncE, buf, 6); - _PrintTitle("CISTPL_FUNCE Fun0"); - _PrintField("BL_SIZE %u", (uint16_t)buf[4] << 8 | buf[3]); - _PrintField("MAX_TRAN_SPD 0x%02X", buf[5]); - } - /* I/O function 1 */ - SDIO_ReadDirect(sdmmcp, SDIO_CIA, SDIO_FBR_ADDR(1, SDIO_FBR_CIS_PTR), - p, 3); - addrFuncE = 0; - /* TODO Augment SdioFindTuples so it finds CISTPL_FUNCE for Function 1 - * with Extended Data 01h */ - SdioFindTuples(sdmmcp, tmp, 256, NULL, &addrFuncE); - if (addrFuncE != 0) { - SDIO_ReadDirect(sdmmcp, SDIO_CIA, addrFuncE, buf, 16); - _PrintTitle("CISTPL_FUNCE Fun1"); - _PrintField("MAX_BLK_SIZE %u", (uint16_t)buf[0xf] << 8 - | buf[0xe]); - } -} -#endif - -#endif diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.h deleted file mode 100644 index a2eba6649..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef CH_SDMMC_SDIO_H_ -#define CH_SDMMC_SDIO_H_ - - - -/** \addtogroup sdio_api - * @{ - */ - -/*---------------------------------------------------------------------------- - * Constants - *----------------------------------------------------------------------------*/ - -/** \addtogroup sdio_status SDIO Status bits - * @{ - */ -#define SDIO_R1_IDLE (1ul << 0) /**< in idle state */ -#define SDIO_R1_ILLEGAL_COMMAND (1ul << 2) /**< illegal command */ -#define SDIO_R1_COM_CRC_ERROR (1ul << 3) /**< COM CRC error */ -#define SDIO_R1_FUNCN_ERROR (1ul << 4) /**< Function number error */ -#define SDIO_R1_PARAM_ERROR (1ul << 6) /**< Parameter error */ - -#define SDIO_R6_COM_CRC_ERROR (1ul << 15) /**< CRC check of command fails */ -#define SDIO_R6_ILLEGAL_COMMAND (1ul << 14) /**< Command not legal for the state */ -#define SDIO_R6_ERROR (1ul << 13) /**< General or unknown error */ - -#define SDIO_R5_Pos (8) /**< R5 starting position */ -#define SDIO_R5_COM_CRC_ERROR (1ul << 15) -#define SDIO_R5_ILLEGAL_COMMAND (1ul << 14) -#define SDIO_R5_IO_STATE (3ul << 12) /**< DIS/CMD/TRN/RFU */ -#define SDIO_R5_STATE_DIS (0ul << 12) -#define SDIO_R5_STATE_CMD (1ul << 12) -#define SDIO_R5_STATE_TRN (2ul << 12) -#define SDIO_R5_STATE_RFU (3ul << 12) -#define SDIO_R5_ERROR (1ul << 11) -#define SDIO_R5_FUNCN_ERROR (1ul << 9) -#define SDIO_R5_OUT_OF_RANGE (1ul << 8) - -#define SDIO_R4_OCR (0xF << 0) /**< OCR */ -#define SDIO_R4_MP (1ul << 27) /**< Memory Present */ -#define SDIO_R4_NF (3ul << 28) /**< Number of Functions */ -/** @}*/ - -/** \addtogroup sdio_fun_def SDIO Functions - * Here lists SDIO functions definitions - * - \ref SDIO_CIA or \ref SDIO_FN0 - * - \ref SDIO_FN1 - * - \ref SDIO_FN2 - * - \ref SDIO_FN3 - * - \ref SDIO_FN4 - * - \ref SDIO_FN5 - * - \ref SDIO_FN6 - * - \ref SDIO_FN7 - * @{*/ -#define SDIO_CIA 0 /**< SDIO Function 0 (CIA) */ -#define SDIO_FN0 0 /**< SDIO Function 0 */ -#define SDIO_FN1 1 /**< SDIO Function 1 */ -#define SDIO_FN2 2 /**< SDIO Function 2 */ -#define SDIO_FN3 3 /**< SDIO Function 3 */ -#define SDIO_FN4 4 /**< SDIO Function 4 */ -#define SDIO_FN5 5 /**< SDIO Function 5 */ -#define SDIO_FN6 6 /**< SDIO Function 6 */ -#define SDIO_FN7 7 /**< SDIO Function 7 */ -/** @}*/ - -/** \addtogroup sdio_cccr_def SDIO Card Common Control Registers (CCCR) - * Here lists SDIO CCCR definitions - * -# \ref SDIO_CCCR_REG - * -# \ref SDIO_SD_REV_REG - * -# \ref SDIO_IOE_REG - * -# \ref SDIO_IOR_REG - * -# \ref SDIO_IEN_REG - * -# \ref SDIO_INT_REG - * -# \ref SDIO_IOA_REG - * -# \ref SDIO_BUS_CTRL_REG - * -# \ref SDIO_CAP_REG - * -# \ref SDIO_CIS_PTR_REG - * -# . - * -# . - * -# \ref SDIO_BUS_SUSP_REG - * -# \ref SDIO_FUN_SEL_REG - * -# \ref SDIO_EXEC_REG - * -# \ref SDIO_READY_REG - * -# \ref SDIO_FN0_BLKSIZ_REG - * -# . - * -# \ref SDIO_POWER_REG - * -# \ref SDIO_HS_REG - * @{*/ -#define SDIO_CCCR_REG 0x00 /**< CCCR/SDIO revision (RO) */ -#define SDIO_CCCR (0xFUL << 0)/**< CCCR Format Version number */ -#define SDIO_CCCR_1_00 (0x0UL << 0)/**< CCCR/FBR Version 1.00 */ -#define SDIO_CCCR_1_10 (0x1UL << 0)/**< CCCR/FBR Version 1.10 */ -#define SDIO_CCCR_1_20 (0x2UL << 0)/**< CCCR/FBR Version 1.20 */ -#define SDIO_SDIO (0xFUL << 4)/**< SDIO Specification */ -#define SDIO_SDIO_1_00 (0x0UL << 4)/**< SDIO Specification 1.00 */ -#define SDIO_SDIO_1_10 (0x1UL << 4)/**< SDIO Specification 1.10 */ -#define SDIO_SDIO_1_20 (0x2UL << 4)/**< SDIO Specification 1.20(unreleased) */ -#define SDIO_SDIO_2_00 (0x3UL << 4)/**< SDIO Specification Version 2.00 */ -#define SDIO_SD_REV_REG 0x01 /**< SD Specification Revision (RO) */ -#define SDIO_SD (0xFUL << 0)/**< SD Physical Specification */ -#define SDIO_SD_1_01 (0x0UL << 0)/**< SD 1.01 (Mar 2000) */ -#define SDIO_SD_1_10 (0x1UL << 0)/**< SD 1.10 (Oct 2004) */ -#define SDIO_SD_2_00 (0x2UL << 0)/**< SD 2.00 (May 2006) */ -#define SDIO_IOE_REG 0x02 /**< I/O Enable (R/W) */ -#define SDIO_IOE 0xFEUL /**< Enable/Disable Function */ -#define SDIO_IOE_FN1 (0x1UL << 1)/**< Function 1 Enable/Disable */ -#define SDIO_IOE_FN2 (0x1UL << 2)/**< Function 2 Enable/Disable */ -#define SDIO_IOE_FN3 (0x1UL << 3)/**< Function 3 Enable/Disable */ -#define SDIO_IOE_FN4 (0x1UL << 4)/**< Function 4 Enable/Disable */ -#define SDIO_IOE_FN5 (0x1UL << 5)/**< Function 5 Enable/Disable */ -#define SDIO_IOE_FN6 (0x1UL << 6)/**< Function 6 Enable/Disable */ -#define SDIO_IOE_FN7 (0x1UL << 7)/**< Function 7 Enable/Disable */ -#define SDIO_IOR_REG 0x03 /**< I/O Ready (RO) */ -#define SDIO_IOR 0xFEUL /**< I/O Function Ready */ -#define SDIO_IOR_FN1 (0x1UL << 1)/**< Function 1 ready */ -#define SDIO_IOR_FN2 (0x1UL << 2)/**< Function 2 ready */ -#define SDIO_IOR_FN3 (0x1UL << 3)/**< Function 3 ready */ -#define SDIO_IOR_FN4 (0x1UL << 4)/**< Function 4 ready */ -#define SDIO_IOR_FN5 (0x1UL << 5)/**< Function 5 ready */ -#define SDIO_IOR_FN6 (0x1UL << 6)/**< Function 6 ready */ -#define SDIO_IOR_FN7 (0x1UL << 7)/**< Function 7 ready */ -#define SDIO_IEN_REG 0x04 /**< Int Enable */ -#define SDIO_IENM 0x01UL /**< Int Enable Master (R/W) */ -#define SDIO_IEN 0xFEUL /**< Int Enable for function (R/W) */ -#define SDIO_IEN_FN1 (0x1UL << 1)/**< Function 1 Int Enable */ -#define SDIO_IEN_FN2 (0x1UL << 2)/**< Function 2 Int Enable */ -#define SDIO_IEN_FN3 (0x1UL << 3)/**< Function 3 Int Enable */ -#define SDIO_IEN_FN4 (0x1UL << 4)/**< Function 4 Int Enable */ -#define SDIO_IEN_FN5 (0x1UL << 5)/**< Function 5 Int Enable */ -#define SDIO_IEN_FN6 (0x1UL << 6)/**< Function 6 Int Enable */ -#define SDIO_IEN_FN7 (0x1UL << 7)/**< Function 7 Int Enable */ -#define SDIO_INT_REG 0x05 /**< Int Pending */ -#define SDIO_INT 0xFE /**< Int Pending for functions (RO) */ -#define SDIO_INT_FN1 (0x1UL << 1)/**< Function 1 Int pending */ -#define SDIO_INT_FN2 (0x1UL << 2)/**< Function 2 Int pending */ -#define SDIO_INT_FN3 (0x1UL << 3)/**< Function 3 Int pending */ -#define SDIO_INT_FN4 (0x1UL << 4)/**< Function 4 Int pending */ -#define SDIO_INT_FN5 (0x1UL << 5)/**< Function 5 Int pending */ -#define SDIO_INT_FN6 (0x1UL << 6)/**< Function 6 Int pending */ -#define SDIO_INT_FN7 (0x1UL << 7)/**< Function 7 Int pending */ -#define SDIO_IOA_REG 0x06 /**< I/O Abort */ -#define SDIO_AS (0x7UL << 0)/**< Abort Select In Order (WO) */ -#define SDIO_AS_FN1 (0x1UL << 0)/**< Abort function 1 IO */ -#define SDIO_AS_FN2 (0x2UL << 0)/**< Abort function 2 IO */ -#define SDIO_AS_FN3 (0x3UL << 0)/**< Abort function 3 IO */ -#define SDIO_AS_FN4 (0x4UL << 0)/**< Abort function 4 IO */ -#define SDIO_AS_FN5 (0x5UL << 0)/**< Abort function 5 IO */ -#define SDIO_AS_FN6 (0x6UL << 0)/**< Abort function 6 IO */ -#define SDIO_AS_FN7 (0x7UL << 0)/**< Abort function 7 IO */ -#define SDIO_RES (0x1UL << 3)/**< IO CARD RESET (WO) */ -#define SDIO_BUS_CTRL_REG 0x07 /**< Bus Interface Control */ -#define SDIO_BUSWIDTH (0x3UL << 0)/**< Data bus width (R/W) */ -#define SDIO_BUSWIDTH_1B (0x0UL << 0)/**< 1-bit data bus */ -#define SDIO_BUSWIDTH_4B (0x2UL << 0)/**< 4-bit data bus */ -#define SDIO_ECSI (0x1UL << 5)/**< Enable Continuous SPI interrupt (R/W) */ -#define SDIO_SCSI (0x1UL << 6)/**< Support Continuous SPI interrupt (RO) */ -#define SDIO_CD (0x1UL << 7)/**< Connect(0)/Disconnect(1) pull-up on CD/DAT[3] (R/W) */ -#define SDIO_CAP_REG 0x08 /**< Card Capability */ -#define SDIO_SDC (0x1UL << 0)/**< Support Direct Commands during data transfer (RO) */ -#define SDIO_SMB (0x1UL << 1)/**< Support Multi-Block (RO) */ -#define SDIO_SRW (0x1UL << 2)/**< Support Read Wait (RO) */ -#define SDIO_SBS (0x1UL << 3)/**< Support Suspend/Resume (RO) */ -#define SDIO_S4MI (0x1UL << 4)/**< Support interrupt between blocks of data in 4-bit SD mode (RO) */ -#define SDIO_E4MI (0x1UL << 5)/**< Enable interrupt between blocks of data in 4-bit SD mode (R/W) */ -#define SDIO_LSC (0x1UL << 6)/**< Low-Speed Card (RO) */ -#define SDIO_4BLS (0x1UL << 7)/**< 4-bit support for Low-Speed Card (RO) */ -#define SDIO_CIS_PTR_REG 0x09 /**< Pointer to CIS (3B, LSB first) */ -#define SDIO_BUS_SUSP_REG 0x0C /**< Bus Suspend */ -#define SDIO_BS (0x1UL << 0)/**< Bus Status (transfer on DAT[x] lines) (RO) */ -#define SDIO_BR (0x1UL << 1)/**< Bus Release Request/Status (R/W) */ -#define SDIO_FUN_SEL_REG 0x0D /**< Function select */ -#define SDIO_DF (0x1UL << 7)/**< Resume Data Flag (RO) */ -#define SDIO_FS (0xFUL << 0)/**< Select Function (R/W) */ -#define SDIO_FS_CIA (0x0UL << 0)/**< Select CIA (function 0) */ -#define SDIO_FS_FN1 (0x1UL << 0)/**< Select Function 1 */ -#define SDIO_FS_FN2 (0x2UL << 0)/**< Select Function 2 */ -#define SDIO_FS_FN3 (0x3UL << 0)/**< Select Function 3 */ -#define SDIO_FS_FN4 (0x4UL << 0)/**< Select Function 4 */ -#define SDIO_FS_FN5 (0x5UL << 0)/**< Select Function 5 */ -#define SDIO_FS_FN6 (0x6UL << 0)/**< Select Function 6 */ -#define SDIO_FS_FN7 (0x7UL << 0)/**< Select Function 7 */ -#define SDIO_FS_MEM (0x8UL << 0)/**< Select memory in combo card */ -#define SDIO_EXEC_REG 0x0E /**< Exec Flags (RO) */ -#define SDIO_EXM (0x1UL << 0)/**< Executing status of memory */ -#define SDIO_EX (0xFEUL) /**< Executing status of functions */ -#define SDIO_EX_FN1 (0x1UL << 1)/**< Executing status of function 1 */ -#define SDIO_EX_FN2 (0x1UL << 2)/**< Executing status of function 2 */ -#define SDIO_EX_FN3 (0x1UL << 3)/**< Executing status of function 3 */ -#define SDIO_EX_FN4 (0x1UL << 4)/**< Executing status of function 4 */ -#define SDIO_EX_FN5 (0x1UL << 5)/**< Executing status of function 5 */ -#define SDIO_EX_FN6 (0x1UL << 6)/**< Executing status of function 6 */ -#define SDIO_EX_FN7 (0x1UL << 7)/**< Executing status of function 7 */ -#define SDIO_READY_REG 0x0F /**< Ready Flags (RO) */ -#define SDIO_RFM (0x1UL << 0)/**< Ready Flag for memory */ -#define SDIO_RF (0xFEUL) /**< Ready Flag for functions */ -#define SDIO_RF_FN1 (0x1UL << 1)/**< Ready Flag for function 1 */ -#define SDIO_RF_FN2 (0x1UL << 2)/**< Ready Flag for function 2 */ -#define SDIO_RF_FN3 (0x1UL << 3)/**< Ready Flag for function 3 */ -#define SDIO_RF_FN4 (0x1UL << 4)/**< Ready Flag for function 4 */ -#define SDIO_RF_FN5 (0x1UL << 5)/**< Ready Flag for function 5 */ -#define SDIO_RF_FN6 (0x1UL << 6)/**< Ready Flag for function 6 */ -#define SDIO_RF_FN7 (0x1UL << 7)/**< Ready Flag for function 7 */ -#define SDIO_FN0_BLKSIZ_REG 0x10 /**< FN0 Block Size (2B, LSB first) (R/W) */ -#define SDIO_POWER_REG 0x12 /**< Power Control */ -#define SDIO_SMPC (0x1UL << 0)/**< Support Master Power Control (RO) */ -#define SDIO_EMPC (0x1UL << 1)/**< Enable Master Power Control (R/W) */ -#define SDIO_HS_REG 0x13 /**< High-Speed */ -#define SDIO_SHS (0x1UL << 0)/**< Support High-Speed (RO) */ -#define SDIO_EHS (0x1UL << 1)/**< Enable High-Speed (R/W) */ -/** @}*/ - -/** \addtogroup sdio_fbr_def SDIO Function Basic Registers (FBR) - * Here lists SDIO Function Basic Register definitions. - * - SDIO_FBR_ADDR() - * -# \ref SDIO_FBR_CSA_IF - * -# \ref SDIO_FBR_EXT_IF - * -# \ref SDIO_FBR_PWR - * -# \ref SDIO_FBR_CIS_PTR - * -# . - * -# . - * -# \ref SDIO_FBR_CSA_PTR - * -# . - * -# . - * -# \ref SDIO_FBR_CSA_DATA - * -# \ref SDIO_FBR_BLK_SIZ - * -# . - * @{*/ -#define SDIO_FBR_ADDR(fn, x) (0x100*(fn) + (x)) -#define SDIO_FBR_CSA_IF 0x0 /**< CSA and function interface code (RO) */ -#define SDIO_IFC (0xFUL << 0)/**< Standard SDIO Fun Interface Code */ -#define SDIO_IFC_NO_IF (0x0UL << 0)/**< No SDIO standard interface */ -#define SDIO_IFC_UART (0x1UL << 0)/**< UART */ -#define SDIO_IFC_TA_BT (0x2UL << 0)/**< Type-A Bluetooth */ -#define SDIO_IFC_TB_BT (0x3UL << 0)/**< Type-B Bluetooth */ -#define SDIO_IFC_GPS (0x4UL << 0)/**< GPS */ -#define SDIO_IFC_CAMERA (0x5UL << 0)/**< Camera */ -#define SDIO_IFC_PHS (0x6UL << 0)/**< PHS */ -#define SDIO_IFC_WLAN (0x7UL << 0)/**< WLAN */ -#define SDIO_IFC_ATA (0x8UL << 0)/**< Embedded SDIO-ATA */ -#define SDIO_IFC_EXT (0xFUL << 0)/**< Check EXT interface code */ -#define SDIO_SCSA (0x1UL << 6)/**< Function supports Code Storage Area (CSA) */ -#define SDIO_FBR_CSA (0x1UL << 7)/**< Function CSA enable */ -#define SDIO_FBR_EXT_IF 0x1 /**< Extended function interface code (RO) */ -#define SDIO_FBR_PWR 0x2 /**< function power control */ -#define SDIO_SPS (0x1UL << 0)/**< function support power selection (RO) */ -#define SDIO_EPS (0x1UL << 1)/**< Low Current Mode/High Current Mode (R/W) */ -#define SDIO_FBR_CIS_PTR 0x9 /**< Address pointer to function CIS (3B, LSB first) (RO) */ -#define SDIO_FBR_CSA_PTR 0xC /**< Address pointer to CSA (3B, LSB first) (R/W) */ -#define SDIO_FBR_CSA_DATA 0xF /**< Read/Write fifo to CSA (R/W) */ -#define SDIO_FBR_BLK_SIZ 0x10 /**< Block size (2B, LSB first) (R/W) */ -/** @}*/ - -/** \addtogroup sdio_meta_def SDIO Card Metaformat - * Here lists definitions for SDIO metaformats. - * - \ref CISTPL_NULL - * - \ref CISTPL_DEVICE - * - \ref CISTPL_CHECKSUM - * - \ref CISTPL_VERS_1 - * - \ref CISTPL_ALTSTR - * - \ref CISTPL_MANFID - * - \ref CISTPL_FUNCID - * - \ref CISTPL_FUNCE - * - \ref CISTPL_SDIO_STD - * - \ref CISTPL_SDIO_EXT - * - \ref CISTPL_END - * @{*/ -#define CISTPL_NULL 0x00 /**< Null tuple (PCMCIA 3.1.9) */ -#define CISTPL_DEVICE 0x01 /**< Device tuple (PCMCIA 3.2.2) */ -#define CISTPL_CHECKSUM 0x10 /**< Checksum control (PCMCIA 3.1.1) */ -#define CISTPL_VERS_1 0x15 /**< Level 1 version (PCMCIA 3.2.10) */ -#define CISTPL_ALTSTR 0x16 /**< Alternate Language String (PCMCIA 3.2.1) */ -#define CISTPL_MANFID 0x20 /**< Manufacturer Identification String (PCMCIA 3.2.9) */ -#define CISTPL_FUNCID 0x21 /**< Function Identification (PCMCIA 3.2.7) */ -#define CISTPL_FUNCE 0x22 /**< Function Extensions (PCMCIA 3.2.6) */ -#define CISTPL_SDIO_STD 0x91 /**< Additional information for SDIO (PCMCIA 6.1.2) */ -#define CISTPL_SDIO_EXT 0x92 /**< Reserved for future SDIO (PCMCIA 6.1.3) */ -#define CISTPL_END 0xFF /**< The End-of-chain Tuple (PCMCIA 3.1.2) */ -/** @}*/ - -/** Status bits mask for SDIO R5 */ -#define STATUS_SDIO_R5 (0/*SDIO_R5_STATE*/ \ - | SDIO_R5_ERROR \ - | SDIO_R5_FUNCN_ERROR \ - | SDIO_R5_OUT_OF_RANGE) - -extern uint8_t SdioInit(SdmmcDriver *driver); -extern uint8_t SDIO_ReadDirect(SdmmcDriver *sdmmcp, - uint8_t functionNum, - uint32_t address, uint8_t * pData, uint32_t size); -extern uint32_t SdioGetMaxFreq(SdmmcDriver *sdmmcp); - -extern void SDIO_DumpCardInformation(SdmmcDriver *sdmmcp); -extern void SDIO_DumpCardInformation(SdmmcDriver *sdmmcp); - -#endif /* CH_SDMMC_SDIO_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_trace.h b/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_trace.h deleted file mode 100644 index 20ea20f50..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_trace.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef CH_SDMMC_TRACE_H_ -#define CH_SDMMC_TRACE_H_ - - -#if SAMA_SDMMC_TRACE == 1 - -#include "chprintf.h" -extern BaseSequentialStream * ts; - -#define TRACE(s) chprintf(ts,s) -#define TRACE_1(s,v1) chprintf(ts,s,v1) -#define TRACE_2(s,v1,v2) chprintf(ts,s,v1,v2) -#define TRACE_3(s,v1,v2,v3) chprintf(ts,s,v1,v3) -#define TRACE_4(s,v1,v2,v3,v4) chprintf(ts,s,v1,v2,v3,v4) -#define TRACE_5(s,v1,v2,v3,v4,v5) chprintf(ts,s,v1,v2,v3,v4,v5) -#define TRACE_6(s,v1,v2,v3,v4,v5,v6) chprintf(ts,s,v1,v2,v3,v4,v5,v6) -#define TRACE_LEV_1(s,v1) TRACE_1(s,v1); -#else -#define TRACE(s) -#define TRACE_1(s,v1) -#define TRACE_2(s,v1,v2) -#define TRACE_3(s,v1,v2,v3) -#define TRACE_4(s,v1,v2,v3,v4) -#define TRACE_5(s,v1,v2,v3,v4,v5) -#define TRACE_6(s,v1,v2,v3,v4,v5,v6) -#endif - -#if SAMA_SDMMC_TRACE_LEVEL >= 1 -#define TRACE_INFO(s) TRACE(s) -#define TRACE_INFO_1(s,v1) TRACE_1(s,v1) -#define TRACE_INFO_2(s,v1,v2) TRACE_2(s,v1,v2) -#define TRACE_INFO_3(s,v1,v2,v3) TRACE_3(s,v1,v2,v3) -#define TRACE_INFO_4(s,v1,v2,v3,v4) TRACE_4(s,v1,v2,v3,v4) -#define TRACE_INFO_5(s,v1,v2,v3,v4,v5) TRACE_5(s,v1,v2,v3,v4,v5) -#define TRACE_INFO_6(s,v1,v2,v3,v4,v5,v6) TRACE_6(s,v1,v2,v3,v4,v5,v6) -#else -#define TRACE_INFO(s) -#define TRACE_INFO_1(s,v1) -#define TRACE_INFO_2(s,v1,v2) -#define TRACE_INFO_3(s,v1,v2,v3) -#define TRACE_INFO_4(s,v1,v2,v3,v4) -#define TRACE_INFO_5(s,v1,v2,v3,v4,v5) -#define TRACE_INFO_6(s,v1,v2,v3,v4,v5,v6) -#endif - - -#if SAMA_SDMMC_TRACE_LEVEL >= 2 -#define TRACE_WARNING(s) TRACE(s) -#define TRACE_WARNING_1(s,v1) TRACE_1(s,v1) -#define TRACE_WARNING_2(s,v1,v2) TRACE_2(s,v1,v2) -#define TRACE_WARNING_3(s,v1,v2,v3) TRACE_3(s,v1,v2,v3) -#define TRACE_WARNING_4(s,v1,v2,v3,v4) TRACE_4(s,v1,v2,v3,v4) -#define TRACE_WARNING_5(s,v1,v2,v3,v4,v5) TRACE_5(s,v1,v2,v3,v4,v5) -#define TRACE_WARNING_6(s,v1,v2,v3,v4,v5,v6) TRACE_6(s,v1,v2,v3,v4,v5,v6) -#else -#define TRACE_WARNING(s) -#define TRACE_WARNING_1(s,v1) -#define TRACE_WARNING_2(s,v1,v2) -#define TRACE_WARNING_3(s,v1,v2,v3) -#define TRACE_WARNING_4(s,v1,v2,v3,v4) -#define TRACE_WARNING_5(s,v1,v2,v3,v4,v5) -#define TRACE_WARNING_6(s,v1,v2,v3,v4,v5,v6) -#endif - - -#if SAMA_SDMMC_TRACE_LEVEL >= 3 -#define TRACE_ERROR(s) TRACE(s) -#define TRACE_ERROR_1(s,v1) TRACE_1(s,v1) -#define TRACE_ERROR_2(s,v1,v2) TRACE_2(s,v1,v2) -#define TRACE_ERROR_3(s,v1,v2,v3) TRACE_3(s,v1,v2,v3) -#define TRACE_ERROR_4(s,v1,v2,v3,v4) TRACE_4(s,v1,v2,v3,v4) -#define TRACE_ERROR_5(s,v1,v2,v3,v4,v5) TRACE_5(s,v1,v2,v3,v4,v5) -#define TRACE_ERROR_6(s,v1,v2,v3,v4,v5,v6) TRACE_6(s,v1,v2,v3,v4,v5,v6) -#else -#define TRACE_ERROR(s) -#define TRACE_ERROR_1(s,v1) -#define TRACE_ERROR_2(s,v1,v2) -#define TRACE_ERROR_3(s,v1,v2,v3) -#define TRACE_ERROR_4(s,v1,v2,v3,v4) -#define TRACE_ERROR_5(s,v1,v2,v3,v4,v5) -#define TRACE_ERROR_6(s,v1,v2,v3,v4,v5,v6) -#endif - -#if SAMA_SDMMC_TRACE_LEVEL >= 4 -#define TRACE_DEBUG(s) TRACE(s) -#define TRACE_DEBUG_1(s,v1) TRACE_1(s,v1) -#define TRACE_DEBUG_2(s,v1,v2) TRACE_2(s,v1,v2) -#define TRACE_DEBUG_3(s,v1,v2,v3) TRACE_3(s,v1,v2,v3) -#define TRACE_DEBUG_4(s,v1,v2,v3,v4) TRACE_4(s,v1,v2,v3,v4) -#define TRACE_DEBUG_5(s,v1,v2,v3,v4,v5) TRACE_5(s,v1,v2,v3,v4,v5) -#define TRACE_DEBUG_6(s,v1,v2,v3,v4,v5,v6) TRACE_6(s,v1,v2,v3,v4,v5,v6) -#else -#define TRACE_DEBUG(s) -#define TRACE_DEBUG_1(s,v1) -#define TRACE_DEBUG_2(s,v1,v2) -#define TRACE_DEBUG_3(s,v1,v2,v3) -#define TRACE_DEBUG_4(s,v1,v2,v3,v4) -#define TRACE_DEBUG_5(s,v1,v2,v3,v4,v5) -#define TRACE_DEBUG_6(s,v1,v2,v3,v4,v5,v6) -#endif - - - -#endif /* CH_SDMMC_TRACE_H_ */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/driver.mk b/os/hal/ports/SAMA/LLD/SDMMCv1/driver.mk deleted file mode 100644 index 49c64f5fc..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/driver.mk +++ /dev/null @@ -1,20 +0,0 @@ -# Configuration files directory -ifeq ($(CONFDIR),) - CONFDIR = . -endif - -MCUCONF := $(strip $(shell cat $(CONFDIR)/mcuconf.h | egrep -e "\#define")) - -ifneq ($(findstring SAMA_USE_SDMMC TRUE,$(MCUCONF)),) - -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_device.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sdio.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_cmds.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_mmc.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc_sd.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/ch_sdmmc.c - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1 - -endif diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_conf.h b/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_conf.h deleted file mode 100644 index 9df0b5d9e..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_conf.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SAMA_SDMMC_CONF_H -#define SAMA_SDMMC_CONF_H - -#include "ch_sdmmc_sama5d2.h" - - - - -#ifndef SAMA_SDMMC_SDMMCDRIVER_IRQ_PRIORITY -#define SAMA_SDMMC_SDMMCDRIVER_IRQ_PRIORITY 4 -#endif - -#ifndef SAMA_SDMMC_TRACE -#define SAMA_SDMMC_TRACE 0 -#endif - -#ifndef SAMA_SDMMC_TRACE_LEVEL -#define SAMA_SDMMC_TRACE_LEVEL 5 -#endif - -/** Default block size for SD/MMC access */ -#ifndef SDMMC_BLOCK_SIZE -#define SDMMC_BLOCK_SIZE 512 -#endif - - -#endif //SAMA_SDMMC_CONF_H - diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.c b/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.c deleted file mode 100644 index 725d52415..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 sama_sdmmc_lld.c - * @brief PLATFORM SDMMC driver - * - * @addtogroup SDMMC - * @{ - */ - -#include "hal.h" -#include "ccportab.h" - -#if (SAMA_USE_SDMMC == TRUE) || defined(__DOXYGEN__) -#include -#include "sama_sdmmc_lld.h" -#include "ch_sdmmc_device.h" -#include "ch_sdmmc_sd.h" -#include "ch_sdmmc_sdio.h" -#include "ch_sdmmc_trace.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief SDMMC1 driver identifier. - */ -#if (PLATFORM_SDMMC_USE_SDMMC1 == TRUE) || defined(__DOXYGEN__) -SdmmcDriver SDMMCD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ -#if (PLATFORM_SDMMC_USE_SDMMC1 == TRUE) -OSAL_IRQ_HANDLER(SAMA_SDMMCD1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - osalSysLockFromISR(); - sdmmc_device_poll(&SDMMCD1); - osalSysUnlockFromISR(); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - - -/** - * @brief Low level SDMMC driver initialization. - * - * @notapi - */ -void sdmmcInit(void) -{ -#if PLATFORM_SDMMC_USE_SDMMC1 == TRUE - /* Driver initialization.*/ - sdmmcObjectInit(&SDMMCD1); -#endif -} - - -/** - * @brief Configures and activates the SDMMC peripheral. - * - * @param[in] sdmmcp pointer to the @p SdmmcDriver object - * - * @notapi - */ -void sdmmcStart(SdmmcDriver *sdmmcp, const SamaSDMMCConfig *config) -{ - - uint8_t rc; - - sdmmcp->config = config; - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX0, (ID_SDMMC0 + sdmmcp->config->slot_id) , SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - sdmmcp->card.EXT = sdmmcp->config->bp; - sdmmcp->card.SSR = &sdmmcp->config->bp[EXT_SIZE]; - sdmmcp->card.SCR = &sdmmcp->config->bp[EXT_SIZE + SSR_SIZE]; - sdmmcp->card.sandbox1 =&sdmmcp->config->bp[EXT_SIZE + SSR_SIZE + SCR_SIZE]; - sdmmcp->card.sandbox2 = &sdmmcp->config->bp[EXT_SIZE + SSR_SIZE + SCR_SIZE + SB1_SIZE]; - - - rc = sdmmc_device_lowlevelcfg(sdmmcp); - - - if (rc) { - - //initialize - sdmmc_device_initialize(sdmmcp); - - if (!sdmmcp->use_polling) { -#if (PLATFORM_SDMMC_USE_SDMMC1 == TRUE) - aicSetSourcePriority( (ID_SDMMC0 + sdmmcp->config->slot_id) ,SAMA_SDMMC_SDMMCDRIVER_IRQ_PRIORITY); - aicSetSourceHandler(ID_SDMMC0 + sdmmcp->config->slot_id,SAMA_SDMMCD1_HANDLER); - aicEnableInt( (ID_SDMMC0 + sdmmcp->config->slot_id) ); -#endif - } - return; - - } - - TRACE_ERROR("Cannot init board for MMC\r\n"); - sdmmcp->state = MCID_INIT_ERROR; - -} - -/** - * @brief Deactivates the SDMMC peripheral. - * - * @param[in] sdmmcp pointer to the @p SdmmcDriver object - * - * @notapi - */ - -void sdmmcStop(SdmmcDriver *sdmmcp) -{ - - - if (sdmmcp->state != MCID_OFF) { - /* Resets the peripheral.*/ - - /* Disables the peripheral.*/ - aicDisableInt( (ID_SDMMC0 + sdmmcp->config->slot_id) ); - - if (sdmmcp->config->slot_id == SDMMC_SLOT0) { - pmcDisableSDMMC0(); - } else if (sdmmcp->config->slot_id == SDMMC_SLOT1) { - pmcDisableSDMMC1(); - } - } -} - -/** - * @brief sends a command . - * - * @param[in] sdmmcp pointer to the @p SdmmcDriver object - * - * @notapi - */ -uint8_t sdmmcSendCmd(SdmmcDriver *sdmmcp) -{ - - uint32_t err; - - uint8_t bRc; - - if (sdmmcp->cmd.bCmd != 55) { - TRACE_INFO_2("Cmd%u(%lx)\n\r", sdmmcp->cmd.bCmd, sdmmcp->cmd.dwArg); - } - - bRc = sdmmc_device_command(sdmmcp); - - - { - /* Poll command status. - * The driver is responsible for detecting and reporting - * timeout conditions. Here we only start a backup timer, in - * case the driver or the peripheral meets an unexpected - * condition. Mind that defining how long a command such as - * WRITE_MULTIPLE_BLOCK could take in total may only lead to an - * experimental value, lesser than the unrealistic theoretical - * maximum. - * Abort the command if the driver is still busy after 30s, - * which equals 30*1000 system ticks. */ - - - sdmmcp->control_param = 1; - sdmmcp->timeout_elapsed = 0; - sdmmcp->timeout_ticks = 30*1000; - sdmmc_device_startTimeCount(sdmmcp); - - do - { - err = sdmmc_device_control(sdmmcp, SDMMC_IOCTL_BUSY_CHECK); - sdmmc_device_checkTimeCount(sdmmcp); - } - while (sdmmcp->control_param && err == SDMMC_OK && !sdmmcp->timeout_elapsed); - - if (err != SDMMC_OK) { - sdmmcp->cmd.bStatus = (uint8_t)err; - } - else if (sdmmcp->control_param) { - sdmmcp->control_param = 0; - - sdmmc_device_control(sdmmcp, SDMMC_IOCTL_CANCEL_CMD); - - sdmmcp->cmd.bStatus = SDMMC_NO_RESPONSE; - } - - } - - bRc = sdmmcp->cmd.bStatus; - - if (bRc == SDMMC_CHANGED) { - TRACE_DEBUG_2("Changed Cmd%u %s\n\r", sdmmcp->cmd.bCmd,SD_StringifyRetCode(bRc)); - } - else if (bRc != SDMMC_OK) { - TRACE_DEBUG_2("OK Cmd%u %s\n\r", sdmmcp->cmd.bCmd,SD_StringifyRetCode(bRc)); - } - else if (sdmmcp->cmd.cmdOp.bmBits.respType == 1 && sdmmcp->cmd.pResp) { - TRACE_DEBUG_2("Resp Cmd%u st %lx\n\r", sdmmcp->cmd.bCmd, *sdmmcp->cmd.pResp); - } - - return bRc; -} - - -void sdmmcObjectInit(SdmmcDriver *sdmmcp) -{ - sdmmcp->state = MCID_OFF; - sdmmcp->timeout_elapsed = -1; - sdmmcp->config = NULL; -} - - -bool sdmmcOpenDevice(SdmmcDriver *sdmmcp) -{ - uint8_t rc; - - rc = sdmmc_device_start(sdmmcp); - - if (rc != SDMMC_OK) { - TRACE_INFO_1("SD/MMC device initialization failed: %d\n\r", rc); - return false; - } - - if (sdmmc_device_identify(sdmmcp) != SDMMC_OK) { - return false; - } - TRACE_INFO("SD/MMC device initialization successful\n\r"); - return true; -} - -bool sdmmcCloseDevice(SdmmcDriver *sdmmcp) -{ - sdmmc_device_deInit(sdmmcp); - return true; -} - -bool sdmmcShowDeviceInfo(SdmmcDriver *sdmmcp) -{ - sSdCard *pSd =&sdmmcp->card; - TRACE_INFO("Show Device Info:\n\r"); - - #ifndef SDMMC_TRIM_INFO - const uint8_t card_type = sdmmcp->card.bCardType; - TRACE_INFO_1("Card Type: %d\n\r", card_type); - #endif - TRACE_INFO("Dumping Status ... \n\r"); - SD_DumpStatus(pSd); - #ifndef SDMMC_TRIM_INFO - if (card_type & CARD_TYPE_bmSDMMC) - SD_DumpCID(pSd); - if (card_type & CARD_TYPE_bmSD) { - SD_DumpSCR(pSd->SCR); - SD_DumpSSR(pSd->SSR); - } - if (card_type & CARD_TYPE_bmSDMMC) - SD_DumpCSD(pSd); - #ifndef SDMMC_TRIM_MMC - if (card_type & CARD_TYPE_bmMMC) - SD_DumpExtCSD(pSd->EXT); - #endif - #ifndef SDMMC_TRIM_SDIO - if (card_type & CARD_TYPE_bmSDIO) - SDIO_DumpCardInformation(sdmmcp); - #endif - - #endif - return true; -} - - -bool CC_WEAK sdmmcGetInstance(uint8_t index, SdmmcDriver **sdmmcp) -{ - (void)index; - (void)sdmmcp; - return false; -} - -#endif /* SAMA_USE_SDMMC == TRUE */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.h b/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.h deleted file mode 100644 index 1526f7ccc..000000000 --- a/os/hal/ports/SAMA/LLD/SDMMCv1/sama_sdmmc_lld.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 sama_sdmmc_lld.h - * @brief PLATFORM SDMMC subsystem low level driver header. - * - * @addtogroup SDMMC - * @{ - */ - -#ifndef SAMA_SDMMC_LLD_H -#define SAMA_SDMMC_LLD_H - -#if (SAMA_USE_SDMMC == TRUE) || defined(__DOXYGEN__) - -#include "ch_sdmmc.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name PLATFORM configuration options - * @{ - */ -/** - * @brief PLATFORM_SDMMC_USE_SDMMC1 driver enable switch. - * @details If set to @p TRUE the support for PLATFORM_SDMMC_USE_SDMMC1 is included. - * @note The default is @p FALSE. - */ -#if !defined(PLATFORM_SDMMC_USE_SDMMC1) || defined(__DOXYGEN__) -#define PLATFORM_SDMMC_USE_SDMMC1 FALSE -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - - -typedef enum { - MCID_OFF, /**< Device not powered */ - MCID_IDLE, /**< Idle */ - MCID_LOCKED, /**< Locked for specific slot */ - MCID_CMD, /**< Processing the command */ - MCID_ERROR, /**< Command error */ - MCID_INIT_ERROR -}sdmmcstate_t; - - - -typedef struct { - - sdmmcslots_t slot_id; - - uint8_t * bp; - - uint32_t * dma_table; - uint32_t dma_table_size; - -} SamaSDMMCConfig; - - -struct SamaSDMMCDriver -{ - volatile sdmmcstate_t state; - const SamaSDMMCConfig *config; - - Sdmmc * regs; /* set of SDMMC hardware registers */ - - uint32_t tctimer_id; /* Timer/Counter peripheral ID (ID_TCx) */ - - - uint32_t dev_freq; /* frequency of clock provided to memory - * device, in Hz */ - - sSdmmcCommand cmd; - sSdCard card; - - - uint16_t blk_index; /* count of data blocks tranferred already, - * in the context of the command and data - * transfer being executed */ - - uint8_t resp_len; /* size of the response, once retrieved, - * in the context of the command being - * executed, expressed in 32-bit words */ - uint8_t tim_mode; /* timing mode aka bus speed mode */ - uint16_t blk_size; /* max data block size, in bytes */ - bool use_polling; /* polling mode */ - bool cmd_line_released; /* handled the Command Complete event */ - bool dat_lines_released; /* handled the Transfer Complete event */ - bool expect_auto_end; /* waiting for completion of Auto CMD12 */ - bool use_set_blk_cnt; /* implicit SET_BLOCK_COUNT command */ - - uint32_t control_param; - uint32_t timeout_ticks; - int8_t timeout_elapsed; - systime_t time,now; - - rtcnt_t timeout_cycles; - rtcnt_t start_cycles; - - -}; - -typedef struct SamaSDMMCDriver SdmmcDriver; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if (PLATFORM_SDMMC_USE_SDMMC1 == TRUE) -extern SdmmcDriver SDMMCD1; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -void sdmmcInit(void); -void sdmmcObjectInit(SdmmcDriver *sdmmcp); -void sdmmcStart(SdmmcDriver *sdmmcp, const SamaSDMMCConfig *config); -void sdmmcStop(SdmmcDriver *sdmmcp); -uint8_t sdmmcSendCmd(SdmmcDriver *sdmmcp); -bool sdmmcOpenDevice(SdmmcDriver *sdmmcp); -bool sdmmcCloseDevice(SdmmcDriver *sdmmcp); -bool sdmmcShowDeviceInfo(SdmmcDriver *sdmmcp); -bool sdmmcGetInstance(uint8_t index, SdmmcDriver **sdmmcp) ; - -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_USE_SDMMC == TRUE */ - -#endif /* SAMA_SDMMC_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/SPIv1/driver.mk b/os/hal/ports/SAMA/LLD/SPIv1/driver.mk deleted file mode 100644 index 3de7158d8..000000000 --- a/os/hal/ports/SAMA/LLD/SPIv1/driver.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c -endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/SPIv1 diff --git a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c b/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c deleted file mode 100644 index 95625ca07..000000000 --- a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_spi_lld.c - * @brief SAMA SPI subsystem low level driver source. - * - * @addtogroup SPI - * @{ - */ - -#include "hal.h" - -#if HAL_USE_SPI || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Enable write protection on SPI registers block. - * - * @param[in] spip pointer to a SPI register block - * - * @notapi - */ -#define spiEnableWP(spip) { \ - spip->SPI_WPMR = SPI_WPMR_WPKEY_PASSWD | SPI_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on SPI registers block. - * - * @param[in] spip pointer to a SPI register block - * - * @notapi - */ -#define spiDisableWP(spip) { \ - spip->SPI_WPMR = SPI_WPMR_WPKEY_PASSWD; \ -} - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief SPI0 driver identifier. - */ -#if SAMA_SPI_USE_SPI0 || defined(__DOXYGEN__) -SPIDriver SPID0; -#endif - -/** - * @brief SPI1 driver identifier. - */ -#if SAMA_SPI_USE_SPI1 || defined(__DOXYGEN__) -SPIDriver SPID1; -#endif - -/** - * @brief SPI FLEXCOM0 driver identifier. - */ -#if SAMA_SPI_USE_FLEXCOM0 || defined(__DOXYGEN__) -SPIDriver FSPID0; -#endif - -/** - * @brief SPI FLEXCOM1 driver identifier. - */ -#if SAMA_SPI_USE_FLEXCOM1 || defined(__DOXYGEN__) -SPIDriver FSPID1; -#endif - -/** - * @brief SPI FLEXCOM2 driver identifier. - */ -#if SAMA_SPI_USE_FLEXCOM2 || defined(__DOXYGEN__) -SPIDriver FSPID2; -#endif - -/** - * @brief SPI FLEXCOM3 driver identifier. - */ -#if SAMA_SPI_USE_FLEXCOM3 || defined(__DOXYGEN__) -SPIDriver FSPID3; -#endif - -/** - * @brief SPI FLEXCOM4 driver identifier. - */ -#if SAMA_SPI_USE_FLEXCOM4 || defined(__DOXYGEN__) -SPIDriver FSPID4; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -static const CACHE_ALIGNED uint8_t dummytx = 0xFFU; -CACHE_ALIGNED static uint8_t dummyrx; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Shared end-of-rx service routine. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(SAMA_SPI_DMA_ERROR_HOOK) - if ((flags & (XDMAC_CIS_RBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_SPI_DMA_ERROR_HOOK(spip); - } -#else - (void)flags; -#endif - - /* Stop everything.*/ - dmaChannelDisable(spip->dmatx); - dmaChannelDisable(spip->dmarx); - -#if (SAMA_SPI_CACHE_USER_MANAGED == FALSE) - /* D-Cache is enabled */ - /* No operation for dummyrx */ - if ((uint32_t) spip->rxbuf != (uint32_t) &dummyrx) - cacheInvalidateRegion(spip->rxbuf, spip->rxbytes); -#endif - - /* Portable SPI ISR code defined in the high level driver, note, it is - a macro.*/ - _spi_isr_code(spip); -} - -/** - * @brief Shared end-of-tx service routine. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(SAMA_SPI_DMA_ERROR_HOOK) - (void)spip; - if ((flags & (XDMAC_CIS_WBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_SPI_DMA_ERROR_HOOK(spip); - } -#else - (void)spip; - (void)flags; -#endif -} -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level SPI driver initialization. - * - * @notapi - */ -void spi_lld_init(void) { - -#if SAMA_SPI_USE_SPI0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_SPI0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&SPID0); - SPID0.spi = SPI0; - SPID0.flexcom = NULL; - SPID0.dmarx = NULL; - SPID0.dmatx = NULL; - SPID0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_SPI0_RX); - SPID0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_SPI0_TX); -#endif /* SAMA_SPI_USE_SPI0 */ - -#if SAMA_SPI_USE_SPI1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_SPI1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&SPID1); - SPID1.spi = SPI1; - SPID1.flexcom = NULL; - SPID1.dmarx = NULL; - SPID1.dmatx = NULL; - SPID1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_SPI1_RX); - SPID1.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_SPI1_TX); -#endif /* SAMA_SPI_USE_SPI1 */ - -#if SAMA_SPI_USE_FLEXCOM0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&FSPID0); - FSPID0.spi = FCOMSPI0; - FSPID0.flexcom = FLEXCOM0; - FSPID0.dmarx = NULL; - FSPID0.dmatx = NULL; - FSPID0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM0_RX); - FSPID0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM0_TX); -#endif /* SAMA_SPI_USE_FLEXCOM0 */ - -#if SAMA_SPI_USE_FLEXCOM1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&FSPID1); - FSPID1.spi = FCOMSPI1; - FSPID1.flexcom = FLEXCOM1; - FSPID1.dmarx = NULL; - FSPID1.dmatx = NULL; - FSPID1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM1_RX); - FSPID1.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM1_TX); -#endif /* SAMA_SPI_USE_FLEXCOM1 */ - -#if SAMA_SPI_USE_FLEXCOM2 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM2, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&FSPID2); - FSPID2.spi = FCOMSPI2; - FSPID2.flexcom = FLEXCOM2; - FSPID2.dmarx = NULL; - FSPID2.dmatx = NULL; - FSPID2.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM2_RX); - FSPID2.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM2_TX); -#endif /* SAMA_SPI_USE_FLEXCOM2 */ - -#if SAMA_SPI_USE_FLEXCOM3 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM3, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&FSPID3); - FSPID3.spi = FCOMSPI3; - FSPID3.flexcom = FLEXCOM3; - FSPID3.dmarx = NULL; - FSPID3.dmatx = NULL; - FSPID3.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM3_RX); - FSPID3.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM3_TX); -#endif /* SAMA_SPI_USE_FLEXCOM3 */ - -#if SAMA_SPI_USE_FLEXCOM4 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM4, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - spiObjectInit(&FSPID4); - FSPID4.spi = FCOMSPI4; - FSPID4.flexcom = FLEXCOM4; - FSPID4.dmarx = NULL; - FSPID4.dmatx = NULL; - FSPID4.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM4_RX); - FSPID4.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM4_TX); -#endif /* SAMA_SPI_USE_FLEXCOM4 */ -} - -/** - * @brief Configures and activates the SPI peripheral. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_start(SPIDriver *spip) { - - /* Configures the peripheral.*/ - - if (spip->state == SPI_STOP) { - -#if SAMA_SPI_USE_SPI0 - if (&SPID0 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_SPI0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_SPI0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - -#if SAMA_SPI0_USE_GCLK -#if SAMA_SPI0_GCLK_DIV > 256 - #error "SPI0 GCLK divider out of range" -#endif - pmcConfigGclk(ID_SPI0, SAMA_SPI0_GCLK_SOURCE, SAMA_SPI0_GCLK_DIV); - pmcEnableGclk(ID_SPI0); -#endif /* SAMA_SPI0_USE_GCLK */ - - /* Enable SPI0 clock */ - pmcEnableSPI0(); - } -#endif /* SAMA_SPI_USE_SPI0 */ -#if SAMA_SPI_USE_SPI1 - if (&SPID1 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_SPI1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_SPI1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - -#if SAMA_SPI1_USE_GCLK -#if SAMA_SPI1_GCLK_DIV > 256 - #error "SPI1 GCLK divider out of range" -#endif - pmcConfigGclk(ID_SPI1, SAMA_SPI1_GCLK_SOURCE, SAMA_SPI1_GCLK_DIV); - pmcEnableGclk(ID_SPI1); -#endif /* SAMA_SPI1_USE_GCLK */ - - /* Enable SPI1 clock */ - pmcEnableSPI1(); - } -#endif /* SAMA_SPI_USE_SPI1 */ -#if SAMA_SPI_USE_FLEXCOM0 - if (&FSPID0 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - /* Enabling SPI on FLEXCOM */ - spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; - -#if SAMA_FSPI0_USE_GCLK -#if SAMA_FSPI0_GCLK_DIV > 256 - #error "FSPI0 GCLK divider out of range" -#endif - pmcConfigGclk(ID_FLEXCOM0, SAMA_FSPI0_GCLK_SOURCE, SAMA_FSPI0_GCLK_DIV); - pmcEnableGclk(ID_FLEXCOM0); -#endif /* SAMA_FSPI0_USE_GCLK */ - - /* Enable FLEXCOM0 clock */ - pmcEnableFLEXCOM0(); - } -#endif /* SAMA_SPI_USE_FLEXCOM0 */ -#if SAMA_SPI_USE_FLEXCOM1 - if (&FSPID1 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - /* Enabling SPI on FLEXCOM */ - spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; - -#if SAMA_FSPI1_USE_GCLK -#if SAMA_FSPI1_GCLK_DIV > 256 - #error "FSPI1 GCLK divider out of range" -#endif - pmcConfigGclk(ID_FLEXCOM1, SAMA_FSPI1_GCLK_SOURCE, SAMA_FSPI1_GCLK_DIV); - pmcEnableGclk(ID_FLEXCOM1); -#endif /* SAMA_FSPI1_USE_GCLK */ - - /* Enable FLEXCOM1 clock */ - pmcEnableFLEXCOM1(); - } -#endif /* SAMA_SPI_USE_FLEXCOM1 */ -#if SAMA_SPI_USE_FLEXCOM2 - if (&FSPID2 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - /* Enabling SPI on FLEXCOM */ - spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; - -#if SAMA_FSPI2_USE_GCLK -#if SAMA_FSPI2_GCLK_DIV > 256 - #error "FSPI2 GCLK divider out of range" -#endif - pmcConfigGclk(ID_FLEXCOM2, SAMA_FSPI2_GCLK_SOURCE, SAMA_FSPI2_GCLK_DIV); - pmcEnableGclk(ID_FLEXCOM2); -#endif /* SAMA_FSPI2_USE_GCLK */ - - /* Enable FLEXCOM2 clock */ - pmcEnableFLEXCOM2(); - } -#endif /* SAMA_SPI_USE_FLEXCOM2 */ -#if SAMA_SPI_USE_FLEXCOM3 - if (&FSPID3 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - /* Enabling SPI on FLEXCOM */ - spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; - -#if SAMA_FSPI3_USE_GCLK -#if SAMA_FSPI3_GCLK_DIV > 256 - #error "FSPI3 GCLK divider out of range" -#endif - pmcConfigGclk(ID_FLEXCOM3, SAMA_FSPI3_GCLK_SOURCE, SAMA_FSPI3_GCLK_DIV); - pmcEnableGclk(ID_FLEXCOM3); -#endif /* SAMA_FSPI3_USE_GCLK */ - - /* Enable FLEXCOM3 clock */ - pmcEnableFLEXCOM3(); - } -#endif /* SAMA_SPI_USE_FLEXCOM3 */ -#if SAMA_SPI_USE_FLEXCOM4 - if (&FSPID4 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_rx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmarx != NULL, "no channel allocated"); - - spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)spi_lld_serve_tx_interrupt, - (void *)spip); - osalDbgAssert(spip->dmatx != NULL, "no channel allocated"); - /* Enabling SPI on FLEXCOM */ - spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; - -#if SAMA_FSPI4_USE_GCLK -#if SAMA_FSPI4_GCLK_DIV > 256 - #error "FSPI4 GCLK divider out of range" -#endif - pmcConfigGclk(ID_FLEXCOM4, SAMA_FSPI4_GCLK_SOURCE, SAMA_FSPI4_GCLK_DIV); - pmcEnableGclk(ID_FLEXCOM4); -#endif /* SAMA_FSPI4_USE_GCLK */ - - /* Enable FLEXCOM4 clock */ - pmcEnableFLEXCOM4(); - } -#endif /* SAMA_SPI_USE_FLEXCOM4 */ - } - - /* Set mode */ - dmaChannelSetMode(spip->dmarx, spip->rxdmamode); - dmaChannelSetMode(spip->dmatx, spip->txdmamode); - - /* Disable write protection */ - spiDisableWP(spip->spi); - - /* Execute a software reset of the SPI twice */ - spip->spi->SPI_CR = SPI_CR_SWRST; - spip->spi->SPI_CR = SPI_CR_SWRST; - - /* SPI configuration */ - spip->spi->SPI_MR = SPI_MR_MSTR | SPI_MR_WDRBT | spip->config->mr; - spip->spi->SPI_MR &= ~SPI_MR_PCS_Msk; - spip->spi->SPI_MR |= SPI_PCS(spip->config->npcs); - spip->spi->SPI_CSR[spip->config->npcs] = spip->config->csr; - - /* if SPI_CSRx_BITS > 8, dma is set to 16 bits */ - if (((spip->spi->SPI_CSR[spip->config->npcs] >> 4) & 0xF) > 0) { - dmaChannelSetMode(spip->dmatx, spip->txdmamode | XDMAC_CC_DWIDTH_HALFWORD); - dmaChannelSetMode(spip->dmarx, spip->rxdmamode | XDMAC_CC_DWIDTH_HALFWORD); - } - - /* Enable SPI */ - spip->spi->SPI_CR |= SPI_CR_SPIEN; - /* Enable write protection. */ - spiEnableWP(spip->spi); -} - -/** - * @brief Deactivates the SPI peripheral. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_stop(SPIDriver *spip) { - - if (spip->state == SPI_READY) { - /* Disable write protection */ - spiDisableWP(spip->spi); - /* Reset SPI */ - spip->spi->SPI_MR = 0; - spip->spi->SPI_CSR[spip->config->npcs] = 0; - /* Disable SPI */ - spip->spi->SPI_CR |= SPI_CR_SPIDIS; - /* Enable write protection */ - spiEnableWP(spip->spi); - - dmaChannelRelease(spip->dmarx); - dmaChannelRelease(spip->dmatx); - -#if SAMA_SPI_USE_SPI0 - if (&SPID0 == spip) - /* Disable SPI0 clock */ - pmcDisableSPI0(); -#if SAMA_SPI0_USE_GCLK - pmcDisableGclk(ID_SPI0); -#endif /* SAMA_SPI0_USE_GCLK */ - -#endif /* SAMA_SPI_USE_SPI0 */ - -#if SAMA_SPI_USE_SPI1 - if (&SPID1 == spip) - /* Disable SPI1 clock */ - pmcDisableSPI1(); - -#if SAMA_SPI1_USE_GCLK - pmcDisableGclk(ID_SPI1); -#endif /* SAMA_SPI1_USE_GCLK */ - -#endif /* SAMA_SPI_USE_SPI1 */ - -#if SAMA_SPI_USE_FLEXCOM0 - if (&FSPID0 == spip) - /* Disable FLEXCOM0 clock */ - pmcDisableFLEXCOM0(); - -#if SAMA_FSPI0_USE_GCLK - pmcDisableGclk(ID_FLEXCOM0); -#endif /* SAMA_FSPI0_USE_GCLK */ - -#endif /* SAMA_SPI_USE_FLEXCOM0 */ - -#if SAMA_SPI_USE_FLEXCOM1 - if (&FSPID1 == spip) - /* Disable FLEXCOM1 clock */ - pmcDisableFLEXCOM1(); - -#if SAMA_FSPI1_USE_GCLK - pmcDisableGclk(ID_FLEXCOM1); -#endif /* SAMA_FSPI1_USE_GCLK */ - -#endif /* SAMA_SPI_USE_FLEXCOM1 */ - -#if SAMA_SPI_USE_FLEXCOM2 - if (&FSPID2 == spip) - /* Disable FLEXCOM2 clock */ - pmcDisableFLEXCOM2(); - -#if SAMA_FSPI2_USE_GCLK - pmcDisableGclk(ID_FLEXCOM2); -#endif /* SAMA_FSPI2_USE_GCLK */ - -#endif /* SAMA_SPI_USE_FLEXCOM2 */ - -#if SAMA_SPI_USE_FLEXCOM3 - if (&FSPID3 == spip) - /* Disable FLEXCOM3 clock */ - pmcDisableFLEXCOM3(); - -#if SAMA_FSPI3_USE_GCLK - pmcDisableGclk(ID_FLEXCOM3); -#endif /* SAMA_FSPI3_USE_GCLK */ - -#endif /* SAMA_SPI_USE_FLEXCOM3 */ - -#if SAMA_SPI_USE_FLEXCOM4 - if (&FSPID4 == spip) - /* Disable FLEXCOM4 clock */ - pmcDisableFLEXCOM4(); - -#if SAMA_FSPI4_USE_GCLK - pmcDisableGclk(ID_FLEXCOM4); -#endif /* SAMA_FSPI4_USE_GCLK */ - -#endif /* SAMA_SPI_USE_FLEXCOM4 */ - } - - spip->txbuf = NULL; - spip->rxbuf = NULL; - spip->rxbytes = 0; -} - -#if (SPI_SELECT_MODE == (SPI_SELECT_MODE_LLD || SPI_SELECT_MODE_PAD || \ - SPI_SELECT_MODE_PORT || SPI_SELECT_MODE_LINE)) || defined(__DOXYGEN__) -/** - * @brief Asserts the slave select signal and prepares for transfers. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_select(SPIDriver *spip) { - /* No implementation on SAMA.*/ -} - -/** - * @brief Deasserts the slave select signal. - * @details The previously selected peripheral is unselected. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_unselect(SPIDriver *spip) { - /* No implementation on SAMA.*/ -} -#endif - -/** - * @brief Exchanges data on the SPI bus. - * @details This asynchronous function starts a simultaneous transmit/receive - * operation. - * @post At the end of the operation the configured callback is invoked. - * @note The buffers are organized as uint8_t arrays for data sizes below or - * equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to be exchanged - * @param[in] txbuf the pointer to the transmit buffer - * @param[out]rxbuf the pointer to the receive buffer - * - * @notapi - */ -void spi_lld_exchange(SPIDriver *spip, size_t n, - const void *txbuf, void *rxbuf) { - - spip->txbuf = txbuf; - spip->rxbuf = rxbuf; - spip->rxbytes = n; - -#if (SAMA_SPI_CACHE_USER_MANAGED == FALSE) - - osalDbgAssert(!((uint32_t) txbuf & (L1_CACHE_BYTES - 1)), "txbuf address not cache aligned"); - osalDbgAssert(!((uint32_t) rxbuf & (L1_CACHE_BYTES - 1)), "rxbuf address not cache aligned"); - - /* - * If size is not multiple of cache line, clean cache region is required. - */ - if (n & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) rxbuf, n); - } - /* Cache is enabled */ - cacheCleanRegion((uint8_t *) txbuf, n); -#endif /* SAMA_SPI_CACHE_USER_MANAGED */ - - /* Writing channel */ - /* Change mode to incremented address for dummytx */ - dmaChannelSetMode(spip->dmatx, spip->txdmamode | XDMAC_CC_SAM_INCREMENTED_AM); - dmaChannelSetSource(spip->dmatx, txbuf); - dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); - dmaChannelSetTransactionSize(spip->dmatx, n); - - /* Reading channel */ - /* Change mode to incremented address */ - dmaChannelSetMode(spip->dmarx, spip->rxdmamode | XDMAC_CC_DAM_INCREMENTED_AM); - dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); - dmaChannelSetDestination(spip->dmarx, rxbuf); - dmaChannelSetTransactionSize(spip->dmarx, n); - - dmaChannelEnable(spip->dmarx); - dmaChannelEnable(spip->dmatx); -} - -/** - * @brief Sends data over the SPI bus. - * @details This asynchronous function starts a transmit operation. - * @post At the end of the operation the configured callback is invoked. - * @note The buffers are organized as uint8_t arrays for data sizes below or - * equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to send - * @param[in] txbuf the pointer to the transmit buffer - * - * @notapi - */ -void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - - spip->txbuf = txbuf; - spip->rxbuf = &dummyrx; - spip->rxbytes = n; - -#if (SAMA_SPI_CACHE_USER_MANAGED == FALSE) - - osalDbgAssert(!((uint32_t) txbuf & (L1_CACHE_BYTES - 1)), "address not cache aligned"); - - /* Cache is enabled */ - cacheCleanRegion((uint8_t *) txbuf, n); -#endif /* SAMA_SPI_CACHE_USER_MANAGED */ - - /* Writing channel */ - - /* Change mode to incremented address for dummytx */ - dmaChannelSetMode(spip->dmatx, spip->txdmamode | XDMAC_CC_SAM_INCREMENTED_AM); - - dmaChannelSetSource(spip->dmatx, txbuf); - dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); - dmaChannelSetTransactionSize(spip->dmatx, n); - - /* Reading channel */ - - /* Change mode from incremented to fixed address for dummyrx */ - dmaChannelSetMode(spip->dmarx, spip->rxdmamode & ~XDMAC_CC_DAM_INCREMENTED_AM); - - dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); - dmaChannelSetDestination(spip->dmarx, &dummyrx); - dmaChannelSetTransactionSize(spip->dmarx, n); - - /* Enable channel. */ - dmaChannelEnable(spip->dmarx); - dmaChannelEnable(spip->dmatx); - - /* Waiting TXEMPTY flag */ - while (!(spip->spi->SPI_SR & SPI_SR_TXEMPTY)) { - ; - } -} - -/** - * @brief Receives data from the SPI bus. - * @details This asynchronous function starts a receive operation. - * @post At the end of the operation the configured callback is invoked. - * @note The buffers are organized as uint8_t arrays for data sizes below or - * equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to receive - * @param[out]rxbuf the pointer to the receive buffer - * - * @notapi - */ -void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - - spip->rxbuf = rxbuf; - spip->rxbytes = n; - -#if (SAMA_SPI_CACHE_USER_MANAGED == FALSE) - - osalDbgAssert(!((uint32_t) rxbuf & (L1_CACHE_BYTES - 1)), "address not cache aligned"); - - /* - * If size is not multiple of cache line, clean cache region is required. - */ - if (n & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) rxbuf, n); - } -#endif /* SAMA_SPI_CACHE_USER_MANAGED */ - - /* Writing channel */ - /* Change mode from incremented to fixed address for dummytx */ - dmaChannelSetMode(spip->dmatx, spip->txdmamode & ~XDMAC_CC_SAM_INCREMENTED_AM); - - dmaChannelSetSource(spip->dmatx, &dummytx); - dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); - dmaChannelSetTransactionSize(spip->dmatx, n); - - /* Reading channel */ - /* Change mode to incremented address */ - dmaChannelSetMode(spip->dmarx, spip->rxdmamode | XDMAC_CC_DAM_INCREMENTED_AM); - - dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); - dmaChannelSetDestination(spip->dmarx, rxbuf); - dmaChannelSetTransactionSize(spip->dmarx, n); - - dmaChannelEnable(spip->dmarx); - dmaChannelEnable(spip->dmatx); -} - -/** - * @brief Exchanges one frame using a polled wait. - * @details This synchronous function exchanges one frame using a polled - * synchronization method. This function is useful when exchanging - * small amount of data on high speed channels, usually in this - * situation is much more efficient just wait for completion using - * polling than suspending the thread waiting for an interrupt. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] frame the data frame to send over the SPI bus - * @return The received data frame from the SPI bus. - */ -uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { - - while((spip->spi->SPI_SR & SPI_SR_TXEMPTY) == 1); - - spip->spi->SPI_TDR = (uint8_t) frame; - - while((spip->spi->SPI_SR & SPI_SR_RDRF) == 0); - - return (uint16_t) spip->spi->SPI_RDR; -} - -#endif /* HAL_USE_SPI */ - -/** @} */ - diff --git a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h b/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h deleted file mode 100644 index df448eaec..000000000 --- a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h +++ /dev/null @@ -1,493 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_spi_lld.h - * @brief SAMA SPI subsystem low level driver header. - * - * @addtogroup SPI - * @{ - */ - -#ifndef HAL_SPI_LLD_H -#define HAL_SPI_LLD_H - -#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Circular mode support flag. - */ -#define SPI_SUPPORTS_CIRCULAR FALSE - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief SPI0 driver enable switch. - * @details If set to @p TRUE the support for SPI0 is included. - */ -#if !defined(SAMA_SPI_USE_SPI0) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_SPI0 FALSE -#endif - -/** - * @brief SPI0 Generic clock enable. - * @details If set to @p TRUE the support for GCLK SPI0 is included. - */ -#if !defined(SAMA_SPI0_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_SPI0_USE_GCLK FALSE -#endif - -/** - * @brief SPI0 Generic clock source. - */ -#if !defined(SAMA_SPI0_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_SPI0_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief SPI0 Generic clock div. - */ -#if !defined(SAMA_SPI0_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_SPI0_GCLK_DIV 21 -#endif - -/** - * @brief SPI1 driver enable switch. - * @details If set to @p TRUE the support for SPI1 is included. - */ -#if !defined(SAMA_SPI_USE_SPI1) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_SPI1 FALSE -#endif - -/** - * @brief SPI1 Generic clock enable. - * @details If set to @p TRUE the support for GCLK SPI1 is included. - */ -#if !defined(SAMA_SPI1_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_SPI1_USE_GCLK FALSE -#endif - -/** - * @brief SPI1 Generic clock source. - */ -#if !defined(SAMA_SPI1_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_SPI1_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief SPI1 Generic clock div. - */ -#if !defined(SAMA_SPI1_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_SPI1_GCLK_DIV 21 -#endif - -/** - * @brief SPI FLEXCOM0 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM0 is included. - */ -#if !defined(SAMA_SPI_USE_FLEXCOM0) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_FLEXCOM0 FALSE -#endif - -/** - * @brief FSPI0 Generic clock enable. - * @details If set to @p TRUE the support for GCLK FSPI0 is included. - */ -#if !defined(SAMA_FSPI0_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_FSPI0_USE_GCLK FALSE -#endif - -/** - * @brief FSPI0 Generic clock source. - */ -#if !defined(SAMA_FSPI0_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_FSPI0_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief FSPI0 Generic clock div. - */ -#if !defined(SAMA_FSPI0_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_FSPI0_GCLK_DIV 21 -#endif - -/** - * @brief SPI FLEXCOM1 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM1 is included. - */ -#if !defined(SAMA_SPI_USE_FLEXCOM1) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_FLEXCOM1 FALSE -#endif - -/** - * @brief FSPI1 Generic clock enable. - * @details If set to @p TRUE the support for GCLK FSPI1 is included. - */ -#if !defined(SAMA_FSPI1_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_FSPI1_USE_GCLK FALSE -#endif - -/** - * @brief FSPI1 Generic clock source. - */ -#if !defined(SAMA_FSPI1_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_FSPI1_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief FSPI1 Generic clock div. - */ -#if !defined(SAMA_FSPI1_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_FSPI1_GCLK_DIV 21 -#endif - -/** - * @brief SPI FLEXCOM2 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM2 is included. - */ -#if !defined(SAMA_SPI_USE_FLEXCOM2) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_FLEXCOM2 FALSE -#endif - -/** - * @brief FSPI2 Generic clock enable. - * @details If set to @p TRUE the support for GCLK FSPI2 is included. - */ -#if !defined(SAMA_FSPI2_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_FSPI2_USE_GCLK FALSE -#endif - -/** - * @brief FSPI2 Generic clock source. - */ -#if !defined(SAMA_FSPI2_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_FSPI2_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief FSPI2 Generic clock div. - */ -#if !defined(SAMA_FSPI2_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_FSPI2_GCLK_DIV 21 -#endif - -/** - * @brief SPI FLEXCOM3 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM3 is included. - */ -#if !defined(SAMA_SPI_USE_FLEXCOM3) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_FLEXCOM3 FALSE -#endif - -/** - * @brief FSPI3 Generic clock enable. - * @details If set to @p TRUE the support for GCLK FSPI3 is included. - */ -#if !defined(SAMA_FSPI3_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_FSPI3_USE_GCLK FALSE -#endif - -/** - * @brief FSPI3 Generic clock source. - */ -#if !defined(SAMA_FSPI3_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_FSPI3_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief FSPI3 Generic clock div. - */ -#if !defined(SAMA_FSPI3_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_FSPI3_GCLK_DIV 21 -#endif - -/** - * @brief SPI FLEXCOM4 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM4 is included. - */ -#if !defined(SAMA_SPI_USE_FLEXCOM4) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_FLEXCOM4 FALSE -#endif - -/** - * @brief FSPI4 Generic clock enable. - * @details If set to @p TRUE the support for GCLK FSPI4 is included. - */ -#if !defined(SAMA_FSPI4_USE_GCLK) || defined(__DOXYGEN__) -#define SAMA_FSPI4_USE_GCLK FALSE -#endif - -/** - * @brief FSPI4 Generic clock source. - */ -#if !defined(SAMA_FSPI4_GCLK_SOURCE) || defined(__DOXYGEN__) -#define SAMA_FSPI4_GCLK_SOURCE SAMA_GCLK_MCK_CLK -#endif - -/** - * @brief FSPI4 Generic clock div. - */ -#if !defined(SAMA_FSPI4_GCLK_DIV) || defined(__DOXYGEN__) -#define SAMA_FSPI4_GCLK_DIV 21 -#endif - -/** - * @brief SPI0 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_SPI0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_SPI0_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief SPI1 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_SPI1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_SPI1_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM0 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM1 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM2 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM3 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM4 DMA interrupt priority level setting. - */ -#if !defined(SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY 4 -#endif -/** @} */ - -/** - * @brief SPI DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(SAMA_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define SAMA_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") -#endif - -/** - * @brief SPI cache managing. - */ -#if !defined(SAMA_SPI_CACHE_USER_MANAGED) || defined(__DOXYGEN__) -#define SAMA_SPI_CACHE_USER_MANAGED FALSE -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ -/** - * @brief At least an SPI unit is in use. - */ -#define SAMA_SPI_USE_SPI (SAMA_SPI_USE_SPI0 || \ - SAMA_SPI_USE_SPI1) - -/** - * @brief At least an FLEXCOM unit is in use. - */ -#define SAMA_SPI_USE_FLEXCOM (SAMA_SPI_USE_FLEXCOM0 || \ - SAMA_SPI_USE_FLEXCOM1 || \ - SAMA_SPI_USE_FLEXCOM2 || \ - SAMA_SPI_USE_FLEXCOM3 || \ - SAMA_SPI_USE_FLEXCOM4) - -#if !SAMA_SPI_USE_SPI0 && !SAMA_SPI_USE_SPI1 && \ - !SAMA_SPI_USE_FLEXCOM0 && !SAMA_SPI_USE_FLEXCOM1 && \ - !SAMA_SPI_USE_FLEXCOM2 && !SAMA_SPI_USE_FLEXCOM3 && \ - !SAMA_SPI_USE_FLEXCOM4 -#error "SPI driver activated but no SPI peripheral assigned" -#endif - -/* Checks on allocation of UARTx units.*/ -#if SAMA_SPI_USE_FLEXCOM0 -#if defined(SAMA_FLEXCOM0_IS_USED) -#error "FSPID0 requires FLEXCOM0 but the peripheral is already used" -#else -#define SAMA_FLEXCOM0_IS_USED -#endif -#endif - -#if SAMA_SPI_USE_FLEXCOM1 -#if defined(SAMA_FLEXCOM1_IS_USED) -#error "FSPID1 requires FLEXCOM1 but the peripheral is already used" -#else -#define SAMA_FLEXCOM1_IS_USED -#endif -#endif - -#if SAMA_SPI_USE_FLEXCOM2 -#if defined(SAMA_FLEXCOM2_IS_USED) -#error "FSPID2 requires FLEXCOM2 but the peripheral is already used" -#else -#define SAMA_FLEXCOM2_IS_USED -#endif -#endif - -#if SAMA_SPI_USE_FLEXCOM3 -#if defined(SAMA_FLEXCOM3_IS_USED) -#error "FSPID3 requires FLEXCOM3 but the peripheral is already used" -#else -#define SAMA_FLEXCOM3_IS_USED -#endif -#endif - -#if SAMA_SPI_USE_FLEXCOM4 -#if defined(SAMA_FLEXCOM4_IS_USED) -#error "FSPID4 requires FLEXCOM4 but the peripheral is already used" -#else -#define SAMA_FLEXCOM4_IS_USED -#endif -#endif - -#if SPI_SELECT_MODE == (SPI_SELECT_MODE_LLD || SPI_SELECT_MODE_PAD || \ - SPI_SELECT_MODE_PORT || SPI_SELECT_MODE_LINE) -#error "SPI_SELECT_MODE_NONE is supported by this driver" -#endif - -#if !defined(SAMA_DMA_REQUIRED) -#define SAMA_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -#define spi_lld_driver_fields \ - /* Pointer to the SPIx registers block.*/ \ - Spi *spi; \ - /* Pointer to the FLEXCOMx registers block.*/ \ - Flexcom *flexcom; \ - /* Receive DMA stream.*/ \ - sama_dma_channel_t *dmarx; \ - /* Transmit DMA stream.*/ \ - sama_dma_channel_t *dmatx; \ - /* RX DMA mode bit mask.*/ \ - uint32_t rxdmamode; \ - /* TX DMA mode bit mask.*/ \ - uint32_t txdmamode; \ - /* Pointer to the TX buffer location.*/ \ - const uint8_t *txbuf; \ - /* Pointer to the RX buffer location.*/ \ - uint8_t *rxbuf; \ - /* Number of bytes in RX phase.*/ \ - size_t rxbytes; - -/** - * @brief Low level fields of the SPI configuration structure. - */ -#define spi_lld_config_fields \ - /* The chip select line number.*/ \ - uint8_t npcs; \ - /* SPI MR register initialization data.*/ \ - uint32_t mr; \ - /* SPI CSR register initialization data.*/ \ - uint32_t csr; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -#define SPI_PCS(npcs) SPI_MR_PCS((~(1 << npcs) & 0xF)) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if SAMA_SPI_USE_SPI0 && !defined(__DOXYGEN__) -extern SPIDriver SPID0; -#endif - -#if SAMA_SPI_USE_SPI1 && !defined(__DOXYGEN__) -extern SPIDriver SPID1; -#endif - -#if SAMA_SPI_USE_FLEXCOM0 && !defined(__DOXYGEN__) -extern SPIDriver FSPID0; -#endif - -#if SAMA_SPI_USE_FLEXCOM1 && !defined(__DOXYGEN__) -extern SPIDriver FSPID1; -#endif - -#if SAMA_SPI_USE_FLEXCOM2 && !defined(__DOXYGEN__) -extern SPIDriver FSPID2; -#endif - -#if SAMA_SPI_USE_FLEXCOM3 && !defined(__DOXYGEN__) -extern SPIDriver FSPID3; -#endif - -#if SAMA_SPI_USE_FLEXCOM4 && !defined(__DOXYGEN__) -extern SPIDriver FSPID4; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void spi_lld_init(void); - void spi_lld_start(SPIDriver *spip); - void spi_lld_stop(SPIDriver *spip); - void spi_lld_select(SPIDriver *spip); - void spi_lld_unselect(SPIDriver *spip); - void spi_lld_ignore(SPIDriver *spip, size_t n); - void spi_lld_exchange(SPIDriver *spip, size_t n, - const void *txbuf, void *rxbuf); - void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); - void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); - uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); - -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_SPI */ - -#endif /* HAL_SPI_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/USARTv1/driver.mk b/os/hal/ports/SAMA/LLD/USARTv1/driver.mk deleted file mode 100644 index 0bb459670..000000000 --- a/os/hal/ports/SAMA/LLD/USARTv1/driver.mk +++ /dev/null @@ -1,13 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.c -endif -#ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c -#endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.c -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1 diff --git a/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.c b/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.c deleted file mode 100644 index e9ec465f0..000000000 --- a/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 USARTv1/hal_serial_lld.c - * @brief SAMA low level serial driver code. - * - * @addtogroup SERIAL - * @{ - */ - -#include "hal.h" - -#if HAL_USE_SERIAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -#if SAMA_SERIAL_USE_UART -/** - * @brief Enable write protection on SD registers block. - * - * @param[in] sdp pointer to a SD register block - * - * @notapi - */ -#define sdEnableWP(sdp) { \ - sdp->UART_WPMR = UART_WPMR_WPKEY_PASSWD | UART_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on SD registers block. - * - * @param[in] sdp pointer to a SD register block - * - * @notapi - */ -#define sdDisableWP(sdp) { \ - sdp->UART_WPMR = UART_WPMR_WPKEY_PASSWD; \ -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM -/** - * @brief Enable write protection on SD registers block. - * - * @param[in] sdp pointer to a SD register block - * - * @notapi - */ -#define sdFlexEnableWP(sdp) { \ - sdp->US_WPMR = US_WPMR_WPKEY_PASSWD | US_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on SD registers block. - * - * @param[in] sdp pointer to a SD register block - * - * @notapi - */ -#define sdFlexDisableWP(sdp) { \ - sdp->US_WPMR = US_WPMR_WPKEY_PASSWD; \ -} -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief UART0 serial driver identifier.*/ -#if SAMA_SERIAL_USE_UART0 || defined(__DOXYGEN__) -SerialDriver SD0; -#endif - -/** @brief UART1 serial driver identifier.*/ -#if SAMA_SERIAL_USE_UART1 || defined(__DOXYGEN__) -SerialDriver SD1; -#endif - -/** @brief UART2 serial driver identifier.*/ -#if SAMA_SERIAL_USE_UART2 || defined(__DOXYGEN__) -SerialDriver SD2; -#endif - -/** @brief UART3 serial driver identifier.*/ -#if SAMA_SERIAL_USE_UART3 || defined(__DOXYGEN__) -SerialDriver SD3; -#endif - -/** @brief UART4 serial driver identifier.*/ -#if SAMA_SERIAL_USE_UART4 || defined(__DOXYGEN__) -SerialDriver SD4; -#endif - -/** @brief FLEXCOM0 serial driver identifier.*/ -#if SAMA_SERIAL_USE_FLEXCOM0 || defined(__DOXYGEN__) -SerialDriver FSD0; -#endif - -/** @brief FLEXCOM1 serial driver identifier.*/ -#if SAMA_SERIAL_USE_FLEXCOM1 || defined(__DOXYGEN__) -SerialDriver FSD1; -#endif - -/** @brief FLEXCOM2 serial driver identifier.*/ -#if SAMA_SERIAL_USE_FLEXCOM2 || defined(__DOXYGEN__) -SerialDriver FSD2; -#endif - -/** @brief FLEXCOM3 serial driver identifier.*/ -#if SAMA_SERIAL_USE_FLEXCOM3 || defined(__DOXYGEN__) -SerialDriver FSD3; -#endif - -/** @brief FLEXCOM0 serial driver identifier.*/ -#if SAMA_SERIAL_USE_FLEXCOM4 || defined(__DOXYGEN__) -SerialDriver FSD4; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** @brief Driver default configuration.*/ -static const SerialConfig default_config = -{ - SERIAL_DEFAULT_BITRATE, - 0, -#if SAMA_SERIAL_USE_FLEXCOM - US_MR_CHRL_8_BIT | US_MR_PAR_NO -#else - UART_MR_PAR_NO -#endif -}; - -#if SAMA_SERIAL_USE_UART0 || defined(__DOXYGEN__) -/** @brief Input buffer for SD0.*/ -static uint8_t sd_in_buf0[SAMA_SERIAL_UART0_IN_BUF_SIZE]; - -/** @brief Output buffer for SD0.*/ -static uint8_t sd_out_buf0[SAMA_SERIAL_UART0_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_UART1 || defined(__DOXYGEN__) -/** @brief Input buffer for SD1.*/ -static uint8_t sd_in_buf1[SAMA_SERIAL_UART1_IN_BUF_SIZE]; - -/** @brief Output buffer for SD1.*/ -static uint8_t sd_out_buf1[SAMA_SERIAL_UART1_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_UART2 || defined(__DOXYGEN__) -/** @brief Input buffer for SD2.*/ -static uint8_t sd_in_buf2[SAMA_SERIAL_UART2_IN_BUF_SIZE]; - -/** @brief Output buffer for SD2.*/ -static uint8_t sd_out_buf2[SAMA_SERIAL_UART2_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_UART3 || defined(__DOXYGEN__) -/** @brief Input buffer for SD3.*/ -static uint8_t sd_in_buf3[SAMA_SERIAL_UART3_IN_BUF_SIZE]; - -/** @brief Output buffer for SD3.*/ -static uint8_t sd_out_buf3[SAMA_SERIAL_UART3_IN_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_UART4 || defined(__DOXYGEN__) -/** @brief Input buffer for SD4.*/ -static uint8_t sd_in_buf4[SAMA_SERIAL_UART4_IN_BUF_SIZE]; - -/** @brief Output buffer for SD4.*/ -static uint8_t sd_out_buf4[SAMA_SERIAL_UART4_IN_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_FLEXCOM0 || defined(__DOXYGEN__) -/** @brief Input buffer for FSD0.*/ -static uint8_t sdFlex_in_buf0[SAMA_SERIAL_FLEXCOM0_IN_BUF_SIZE]; - -/** @brief Output buffer for FSD0.*/ -static uint8_t sdFlex_out_buf0[SAMA_SERIAL_FLEXCOM0_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_FLEXCOM1 || defined(__DOXYGEN__) -/** @brief Input buffer for FSD1.*/ -static uint8_t sdFlex_in_buf1[SAMA_SERIAL_FLEXCOM1_IN_BUF_SIZE]; - -/** @brief Output buffer for FSD1.*/ -static uint8_t sdFlex_out_buf1[SAMA_SERIAL_FLEXCOM1_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_FLEXCOM2 || defined(__DOXYGEN__) -/** @brief Input buffer for FSD2.*/ -static uint8_t sdFlex_in_buf2[SAMA_SERIAL_FLEXCOM2_IN_BUF_SIZE]; - -/** @brief Output buffer for FSD2.*/ -static uint8_t sdFlex_out_buf2[SAMA_SERIAL_FLEXCOM2_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_FLEXCOM3 || defined(__DOXYGEN__) -/** @brief Input buffer for FSD3.*/ -static uint8_t sdFlex_in_buf3[SAMA_SERIAL_FLEXCOM3_IN_BUF_SIZE]; - -/** @brief Output buffer for FSD3.*/ -static uint8_t sdFlex_out_buf3[SAMA_SERIAL_FLEXCOM3_OUT_BUF_SIZE]; -#endif - -#if SAMA_SERIAL_USE_FLEXCOM4 || defined(__DOXYGEN__) -/** @brief Input buffer for FSD4.*/ -static uint8_t sdFlex_in_buf4[SAMA_SERIAL_FLEXCOM4_IN_BUF_SIZE]; - -/** @brief Output buffer for FSD4.*/ -static uint8_t sdFlex_out_buf4[SAMA_SERIAL_FLEXCOM4_OUT_BUF_SIZE]; -#endif - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief UART initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration - */ -static void uart_init(SerialDriver *sdp, const SerialConfig *config) { -#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM - if (sdp->uart != NULL) -#endif /* SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM */ -#if SAMA_SERIAL_USE_UART - { - Uart *u = sdp->uart; - - /* Disabling write protection */ - sdDisableWP(u); - /* Baud rate setting.*/ - u->UART_BRGR = UART_BRGR_CD(sdp->clock / (16 * config->speed)); - - u->UART_CR = config->cr; - u->UART_MR = config->mr; - u->UART_IER = UART_IER_RXRDY; - - /* Clearing error status bit */ - u->UART_CR |= UART_CR_RSTSTA; - /* Enabling Tx and Rx */ - u->UART_CR |= UART_CR_RXEN | UART_CR_TXEN; - /* Enabling write protection */ - sdEnableWP(u); - } -#endif /* SAMA_SERIAL_USE_UART */ -#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM - else if (sdp->usart != NULL) -#endif /* SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM */ -#if SAMA_SERIAL_USE_FLEXCOM - { - Flexcom *fl = sdp->flexcom; - Usart *us = sdp->usart; - - /* Disabling write protection */ - sdFlexDisableWP(us) - /* Enabling USART on FLEXCOM */ - fl->FLEX_MR = FLEX_MR_OPMODE_USART; - /* Baud rate setting (OVER = 0 and SYNC = 0)*/ - us->US_BRGR = US_BRGR_CD(sdp->clock / (16 * config->speed)); - - us->US_CR = config->cr; - us->US_MR = config->mr; - us->US_IER = US_IER_RXRDY; - - /* Clearing status bit */ - us->US_CR |= US_CR_RSTSTA; - /* Enabling Tx and Rx */ - us->US_CR |= US_CR_RXEN | US_CR_TXEN; - /* Enabling write protection */ - sdFlexEnableWP(us) - } -#endif /* SAMA_SERIAL_USE_FLEXCOM */ -#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM - else { - osalDbgAssert(FALSE, "invalid state"); - } -#endif /* SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM */ -} - -/** - * @brief USART de-initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] u pointer to an UART I/O block - */ -static void uart_deinit(SerialDriver *sdp) { -#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM - if (sdp->uart != NULL) -#endif /* SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM */ -#if SAMA_SERIAL_USE_UART - { - Uart *u = sdp->uart; - /* Disabling write protection */ - sdDisableWP(u); - u->UART_CR = 0; - u->UART_MR = 0; - /* Enabling write protection */ - sdEnableWP(u); - } -#endif /* SAMA_SERIAL_USE_UART */ -#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM - else if (sdp->usart != NULL) -#endif /* SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM */ -#if SAMA_SERIAL_USE_FLEXCOM - { - Usart *us = sdp->usart; - - /* Disabling write protection */ - sdFlexDisableWP(us) - us->US_CR = 0; - us->US_MR = 0; - - /* Enabling write protection */ - sdFlexEnableWP(us) - } -#endif /* SAMA_SERIAL_USE_FLEXCOM */ -#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM - else { - osalDbgAssert(FALSE, "invalid state"); - } -#endif /* SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM */ -} - -/** - * @brief Error handling routine. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] isr USART ISR register value - */ -static void set_error(SerialDriver *sdp, uint32_t isr) { - eventflags_t sts = 0; - - if (isr & (UART_SR_OVRE | US_CSR_OVRE)) - sts |= SD_OVERRUN_ERROR; - if (isr & (UART_SR_PARE | US_CSR_PARE)) - sts |= SD_PARITY_ERROR; - if (isr & (UART_SR_FRAME | US_CSR_FRAME)) - sts |= UART_SR_FRAME; - osalSysLockFromISR(); - chnAddFlagsI(sdp, sts); - osalSysUnlockFromISR(); -} - -#if SAMA_SERIAL_USE_UART -/** - * @brief Common IRQ handler. - * - * @param[in] sdp communication channel associated to the UART - */ -static void serve_interrupt(SerialDriver *sdp) { - Uart *u = sdp->uart; - uint32_t imr = u->UART_IMR; - uint32_t sr; - - /* Reading and clearing status.*/ - sr = u->UART_SR; - u->UART_CR |= UART_CR_RSTSTA; - - /* Error condition detection.*/ - if (sr & (UART_SR_OVRE | UART_SR_FRAME | UART_SR_PARE)){ - set_error(sdp, sr); - } - - /* Data available.*/ - if (sr & UART_SR_RXRDY) { - osalSysLockFromISR(); - sdIncomingDataI(sdp, (uint8_t)u->UART_RHR); - osalSysUnlockFromISR(); - } - - /* Transmission buffer empty.*/ - if ((imr & UART_IMR_TXRDY) && (sr & UART_SR_TXRDY)) { - msg_t b; - osalSysLockFromISR(); - b = oqGetI(&sdp->oqueue); - if (b < MSG_OK) { - chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); - u->UART_IDR |= UART_IDR_TXRDY; - u->UART_IER = UART_IER_TXEMPTY; - } - else - u->UART_THR = b; - osalSysUnlockFromISR(); - } - - /* Physical transmission end.*/ - if ((imr & UART_IMR_TXEMPTY) && (sr & (UART_SR_TXRDY | UART_SR_TXEMPTY))) { - osalSysLockFromISR(); - if (oqIsEmptyI(&sdp->oqueue)) - chnAddFlagsI(sdp, CHN_TRANSMISSION_END); - u->UART_IDR |= UART_IDR_TXRDY | UART_IDR_TXEMPTY; - osalSysUnlockFromISR(); - } -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM -/** - * @brief Common IRQ handler. - * - * @param[in] sdp communication channel associated to the UART - */ -static void serve_uartFlex_interrupt(SerialDriver *sdp) { - Usart *us = sdp->usart; - uint32_t imr = us->US_IMR; - uint32_t sr; - - /* Reading and clearing status.*/ - sr = us->US_CSR; - us->US_CR |= US_CR_RSTSTA; - - /* Error condition detection.*/ - if (sr & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE)){ - set_error(sdp, sr); - } - - /* Data available.*/ - if (sr & US_CSR_RXRDY) { - osalSysLockFromISR(); - sdIncomingDataI(sdp, (uint8_t)us->US_RHR); - osalSysUnlockFromISR(); - } - - /* Transmission buffer empty.*/ - if ((imr & US_IMR_TXRDY) && (sr & US_CSR_TXRDY)) { - msg_t b; - osalSysLockFromISR(); - b = oqGetI(&sdp->oqueue); - if (b < MSG_OK) { - chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); - us->US_IDR |= US_IDR_TXRDY; - us->US_IER = US_IER_TXEMPTY; - } - else - us->US_THR = b; - osalSysUnlockFromISR(); - } - - /* Physical transmission end.*/ - if ((imr & US_IMR_TXEMPTY) && (sr & (US_CSR_TXRDY | US_CSR_TXEMPTY))) { - osalSysLockFromISR(); - if (oqIsEmptyI(&sdp->oqueue)) - chnAddFlagsI(sdp, CHN_TRANSMISSION_END); - us->US_IDR |= US_IDR_TXRDY | US_IDR_TXEMPTY; - osalSysUnlockFromISR(); - } -} -#endif - -#if SAMA_SERIAL_USE_UART0 || defined(__DOXYGEN__) -static void notify0(io_queue_t *qp) { - - (void)qp; - UART0->UART_IER |= UART_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_UART1 || defined(__DOXYGEN__) -static void notify1(io_queue_t *qp) { - - (void)qp; - UART1->UART_IER |= UART_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_UART2 || defined(__DOXYGEN__) -static void notify2(io_queue_t *qp) { - - (void)qp; - UART2->UART_IER |= UART_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_UART3 || defined(__DOXYGEN__) -static void notify3(io_queue_t *qp) { - - (void)qp; - UART3->UART_IER |= UART_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_UART4 || defined(__DOXYGEN__) -static void notify4(io_queue_t *qp) { - - (void)qp; - UART4->UART_IER |= UART_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM0 || defined(__DOXYGEN__) -static void notifyFlex0(io_queue_t *qp) { - - (void)qp; - USART0->US_IER |= US_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM1 || defined(__DOXYGEN__) -static void notifyFlex1(io_queue_t *qp) { - - (void)qp; - USART1->US_IER |= US_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM2 || defined(__DOXYGEN__) -static void notifyFlex2(io_queue_t *qp) { - - (void)qp; - USART2->US_IER |= US_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM3 || defined(__DOXYGEN__) -static void notifyFlex3(io_queue_t *qp) { - - (void)qp; - USART3->US_IER |= US_IER_TXRDY; -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM4 || defined(__DOXYGEN__) -static void notifyFlex4(io_queue_t *qp) { - - (void)qp; - USART4->US_IER |= US_IER_TXRDY; -} -#endif - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if SAMA_SERIAL_USE_UART0 || defined(__DOXYGEN__) -/** - * @brief UART0 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_interrupt(&SD0); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_UART1 || defined(__DOXYGEN__) -/** - * @brief UART1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_interrupt(&SD1); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_UART2 || defined(__DOXYGEN__) -/** - * @brief UART2 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_interrupt(&SD2); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_UART3 || defined(__DOXYGEN__) -/** - * @brief UART3 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_interrupt(&SD3); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_UART4 || defined(__DOXYGEN__) -/** - * @brief UART4 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_interrupt(&SD4); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM0 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM0 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_interrupt(&FSD0); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM1 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_interrupt(&FSD1); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM2 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM2 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_interrupt(&FSD2); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM3 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM3 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_interrupt(&FSD3); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if SAMA_SERIAL_USE_FLEXCOM4 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM4 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_interrupt(&FSD4); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level serial driver initialization. - * - * @notapi - */ -void sd_lld_init(void) { - -#if SAMA_SERIAL_USE_UART0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&SD0); - iqObjectInit(&SD0.iqueue, sd_in_buf0, sizeof sd_in_buf0, NULL, &SD0); - oqObjectInit(&SD0.oqueue, sd_out_buf0, sizeof sd_out_buf0, notify0, &SD0); - SD0.uart = UART0; - SD0.clock = SAMA_UART0CLK; - - aicSetSourcePriority(ID_UART0, SAMA_SERIAL_UART0_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART0, SAMA_UART0_HANDLER); - aicEnableInt(ID_UART0); -#endif - -#if SAMA_SERIAL_USE_UART1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART1, SECURE_PER); -#endif - sdObjectInit(&SD1); - iqObjectInit(&SD1.iqueue, sd_in_buf1, sizeof sd_in_buf1, NULL, &SD1); - oqObjectInit(&SD1.oqueue, sd_out_buf1, sizeof sd_out_buf1, notify1, &SD1); - SD1.uart = UART1; - SD1.clock = SAMA_UART1CLK; - - aicSetSourcePriority(ID_UART1, SAMA_SERIAL_UART1_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART1, SAMA_UART1_HANDLER); - aicEnableInt(ID_UART1); -#endif - -#if SAMA_SERIAL_USE_UART2 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART2, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&SD2); - iqObjectInit(&SD2.iqueue, sd_in_buf2, sizeof sd_in_buf2, NULL, &SD2); - oqObjectInit(&SD2.oqueue, sd_out_buf2, sizeof sd_out_buf2, notify2, &SD2); - SD2.uart = UART2; - SD2.clock = SAMA_UART2CLK; - - aicSetSourcePriority(ID_UART2, SAMA_SERIAL_UART2_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART2, SAMA_UART2_HANDLER); - aicEnableInt(ID_UART2); -#endif - -#if SAMA_SERIAL_USE_UART3 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART3, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&SD3); - iqObjectInit(&SD3.iqueue, sd_in_buf3, sizeof sd_in_buf3, NULL, &SD3); - oqObjectInit(&SD3.oqueue, sd_out_buf3, sizeof sd_out_buf3, notify3, &SD3); - SD3.uart = UART3; - SD3.clock = SAMA_UART3CLK; - - aicSetSourcePriority(ID_UART3, SAMA_SERIAL_UART3_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART3, SAMA_UART3_HANDLER); - aicEnableInt(ID_UART3); -#endif - -#if SAMA_SERIAL_USE_UART4 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART4, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&SD4); - iqObjectInit(&SD4.iqueue, sd_in_buf4, sizeof sd_in_buf4, NULL, &SD4); - oqObjectInit(&SD4.oqueue, sd_out_buf4, sizeof sd_out_buf4, notify4, &SD4); - SD4.uart = UART4; - SD4.clock = SAMA_UART4CLK; - - aicSetSourcePriority(ID_UART4, SAMA_SERIAL_UART4_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART4, SAMA_UART4_HANDLER); - aicEnableInt(ID_UART4); -#endif - -#if SAMA_SERIAL_USE_FLEXCOM0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&FSD0); - iqObjectInit(&FSD0.iqueue, sdFlex_in_buf0, sizeof sdFlex_in_buf0, NULL, &FSD0); - oqObjectInit(&FSD0.oqueue, sdFlex_out_buf0, sizeof sdFlex_out_buf0, notifyFlex0, &FSD0); - FSD0.flexcom = FLEXCOM0; - FSD0.usart = USART0; - FSD0.clock = SAMA_FLEXCOM0CLK; - - aicSetSourcePriority(ID_USART0, SAMA_SERIAL_FLEXCOM0_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART0, SAMA_SERIAL_FLEXCOM0_HANDLER); - aicEnableInt(ID_USART0); -#endif - -#if SAMA_SERIAL_USE_FLEXCOM1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&FSD1); - iqObjectInit(&FSD1.iqueue, sdFlex_in_buf1, sizeof sdFlex_in_buf1, NULL, &FSD1); - oqObjectInit(&FSD1.oqueue, sdFlex_out_buf1, sizeof sdFlex_out_buf1, notifyFlex1, &FSD1); - FSD1.flexcom = FLEXCOM1; - FSD1.usart = USART1; - FSD1.clock = SAMA_FLEXCOM1CLK; - - aicSetSourcePriority(ID_USART1, SAMA_SERIAL_FLEXCOM1_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART1, SAMA_SERIAL_FLEXCOM1_HANDLER); - aicEnableInt(ID_USART1); -#endif - -#if SAMA_SERIAL_USE_FLEXCOM2 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM2, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&FSD2); - iqObjectInit(&FSD2.iqueue, sdFlex_in_buf2, sizeof sdFlex_in_buf2, NULL, &FSD2); - oqObjectInit(&FSD2.oqueue, sdFlex_out_buf2, sizeof sdFlex_out_buf2, notifyFlex2, &FSD2); - FSD2.flexcom = FLEXCOM2; - FSD2.usart = USART2; - FSD2.clock = SAMA_FLEXCOM2CLK; - - aicSetSourcePriority(ID_USART2, SAMA_SERIAL_FLEXCOM2_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART2, SAMA_SERIAL_FLEXCOM2_HANDLER); - aicEnableInt(ID_USART2); -#endif - -#if SAMA_SERIAL_USE_FLEXCOM3 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM3, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&FSD3); - iqObjectInit(&FSD3.iqueue, sdFlex_in_buf3, sizeof sdFlex_in_buf3, NULL, &FSD3); - oqObjectInit(&FSD3.oqueue, sdFlex_out_buf3, sizeof sdFlex_out_buf3, notifyFlex3, &FSD3); - FSD3.flexcom = FLEXCOM3; - FSD3.usart = USART3; - FSD3.clock = SAMA_FLEXCOM3CLK; - - aicSetSourcePriority(ID_USART3, SAMA_SERIAL_FLEXCOM3_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART3, SAMA_SERIAL_FLEXCOM3_HANDLER); - aicEnableInt(ID_USART3); -#endif - -#if SAMA_SERIAL_USE_FLEXCOM4 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM4, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - sdObjectInit(&FSD4); - iqObjectInit(&FSD4.iqueue, sdFlex_in_buf4, sizeof sdFlex_in_buf4, NULL, &FSD4); - oqObjectInit(&FSD4.oqueue, sdFlex_out_buf4, sizeof sdFlex_out_buf4, notifyFlex4, &FSD4); - FSD4.flexcom = FLEXCOM4; - FSD4.usart = USART4; - FSD4.clock = SAMA_FLEXCOM4CLK; - - aicSetSourcePriority(ID_USART4, SAMA_SERIAL_FLEXCOM4_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART4, SAMA_SERIAL_FLEXCOM4_HANDLER); - aicEnableInt(ID_USART4); -#endif -} - -/** - * @brief Low level serial driver configuration and (re)start. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration. - * If this parameter is set to @p NULL then a default - * configuration is used. - * - * @notapi - */ -void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { - - if (config == NULL) { - - config = &default_config; - } - if (sdp->state == SD_STOP) { -#if SAMA_SERIAL_USE_UART0 - if (&SD0 == sdp) { - pmcEnableUART0(); - } -#endif -#if SAMA_SERIAL_USE_UART1 - if (&SD1 == sdp) { - pmcEnableUART1(); - } -#endif -#if SAMA_SERIAL_USE_UART2 - if (&SD2 == sdp) { - pmcEnableUART2(); - } -#endif -#if SAMA_SERIAL_USE_UART3 - if (&SD3 == sdp) { - pmcEnableUART3(); - } -#endif -#if SAMA_SERIAL_USE_UART4 - if (&SD4 == sdp) { - pmcEnableUART4(); - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM0 - if (&FSD0 == sdp) { - pmcEnableFLEXCOM0(); - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM1 - if (&FSD1 == sdp) { - pmcEnableFLEXCOM1(); - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM2 - if (&FSD2 == sdp) { - pmcEnableFLEXCOM2(); - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM3 - if (&FSD3 == sdp) { - pmcEnableFLEXCOM3(); - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM4 - if (&FSD4 == sdp) { - pmcEnableFLEXCOM4(); - } -#endif - } - uart_init(sdp, config); -} - -/** - * @brief Low level serial driver stop. - * @details De-initializes the USART, stops the associated clock, resets the - * interrupt vector. - * - * @param[in] sdp pointer to a @p SerialDriver object - * - * @notapi - */ -void sd_lld_stop(SerialDriver *sdp) { - - if (sdp->state == SD_READY) { - /* UART is de-initialized then clocks are disabled.*/ - uart_deinit(sdp); - -#if SAMA_SERIAL_USE_UART0 - if (&SD0 == sdp) { - pmcDisableUART0(); - return; - } -#endif -#if SAMA_SERIAL_USE_UART1 - if (&SD1 == sdp) { - pmcDisableUART1(); - return; - } -#endif -#if SAMA_SERIAL_USE_UART2 - if (&SD2 == sdp) { - pmcDisableUART2(); - return; - } -#endif -#if SAMA_SERIAL_USE_UART3 - if (&SD3 == sdp) { - pmcDisableUART3(); - return; - } -#endif -#if SAMA_SERIAL_USE_UART4 - if (&SD4 == sdp) { - pmcDisableUART4(); - return; - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM0 - if (&FSD0 == sdp) { - pmcDisableFLEXCOM0(); - return; - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM1 - if (&FSD1 == sdp) { - pmcDisableFLEXCOM1(); - return; - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM2 - if (&FSD2 == sdp) { - pmcDisableFLEXCOM2(); - return; - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM3 - if (&FSD3 == sdp) { - pmcDisableFLEXCOM3(); - return; - } -#endif -#if SAMA_SERIAL_USE_FLEXCOM4 - if (&FSD4 == sdp) { - pmcDisableFLEXCOM4(); - return; - } -#endif - } -} - -#endif /* HAL_USE_SERIAL */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.h b/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.h deleted file mode 100644 index 5a028e522..000000000 --- a/os/hal/ports/SAMA/LLD/USARTv1/hal_serial_lld.h +++ /dev/null @@ -1,567 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 USARTv1/hal_serial_lld.h - * @brief SAMA low level serial driver header. - * - * @addtogroup SERIAL - * @{ - */ - -#ifndef HAL_SERIAL_LLD_H -#define HAL_SERIAL_LLD_H - -#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Advanced buffering support switch. - * @details This constants enables the advanced buffering support in the - * low level driver, the queue buffer is no more part of the - * @p SerialDriver structure, each driver can have a different - * queue size. - */ -#define SERIAL_ADVANCED_BUFFERING_SUPPORT TRUE - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief UART0 driver enable switch. - * @details If set to @p TRUE the support for UART0 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_UART0) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_UART0 FALSE -#endif - -/** - * @brief UART1 driver enable switch. - * @details If set to @p TRUE the support for UART1 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_UART1) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_USART1 FALSE -#endif - -/** - * @brief UART2 driver enable switch. - * @details If set to @p TRUE the support for UART2 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_UART2) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_UART2 FALSE -#endif - -/** - * @brief UART3 driver enable switch. - * @details If set to @p TRUE the support for UART3 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_UART3) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_UART3 FALSE -#endif - -/** - * @brief UART4 driver enable switch. - * @details If set to @p TRUE the support for UART4 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_UART4) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_UART4 FALSE -#endif - -/** - * @brief FLEXCOM0 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM0 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_FLEXCOM0) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_FLEXCOM0 FALSE -#endif - -/** - * @brief FLEXCOM1 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM1 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_FLEXCOM1) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_FLEXCOM1 FALSE -#endif - -/** - * @brief FLEXCOM2 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM2 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_FLEXCOM2) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_FLEXCOM2 FALSE -#endif - -/** - * @brief FLEXCOM3 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM3 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_FLEXCOM3) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_FLEXCOM3 FALSE -#endif - -/** - * @brief FLEXCOM4 driver enable switch. - * @details If set to @p TRUE the support for FLEXCOM4 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_SERIAL_USE_FLEXCOM4) || defined(__DOXYGEN__) -#define SAMA_SERIAL_USE_FLEXCOM4 FALSE -#endif - -/** - * @brief UART0 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_UART0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART0_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART1 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_UART1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART1_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART2 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_UART2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART2_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART3 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_UART3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART3_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART4 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART4_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM0 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_FLEXCOM0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM0_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM1 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_FLEXCOM1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM1_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM2 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_FLEXCOM2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM2_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM3 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_FLEXCOM3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM3_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM4 interrupt priority level setting. - */ -#if !defined(SAMA_SERIAL_FLEXCOM4_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM4_IRQ_PRIORITY 4 -#endif - -/** - * @brief Input buffer size for UART0. - */ -#if !defined(SAMA_SERIAL_UART0_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART0_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for UART0. - */ -#if !defined(SAMA_SERIAL_UART0_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART0_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for UART1. - */ -#if !defined(SAMA_SERIAL_UART1_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART1_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for UART1. - */ -#if !defined(SAMA_SERIAL_UART1_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART1_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for UART2. - */ -#if !defined(SAMA_SERIAL_UART2_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART2_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for UART2. - */ -#if !defined(SAMA_SERIAL_UART2_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART2_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for UART3. - */ -#if !defined(SAMA_SERIAL_UART3_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART3_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for UART3. - */ -#if !defined(SAMA_SERIAL_UART3_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART3_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for UART4. - */ -#if !defined(SAMA_SERIAL_UART4_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART4_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for UART4. - */ -#if !defined(SAMA_SERIAL_UART4_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_UART4_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for FLEXCOM0. - */ -#if !defined(SAMA_SERIAL_FLEXCOM0_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM0_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for FLEXCOM0. - */ -#if !defined(SAMA_SERIAL_FLEXCOM0_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM0_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for FLEXCOM1. - */ -#if !defined(SAMA_SERIAL_FLEXCOM1_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM1_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for FLEXCOM1. - */ -#if !defined(SAMA_SERIAL_FLEXCOM1_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM1_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for FLEXCOM2. - */ -#if !defined(SAMA_SERIAL_FLEXCOM2_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM2_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for FLEXCOM2. - */ -#if !defined(SAMA_SERIAL_FLEXCOM2_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM2_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for FLEXCOM3. - */ -#if !defined(SAMA_SERIAL_FLEXCOM3_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM3_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for FLEXCOM3. - */ -#if !defined(SAMA_SERIAL_FLEXCOM3_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM3_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Input buffer size for FLEXCOM4. - */ -#if !defined(SAMA_SERIAL_FLEXCOM4_IN_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM4_IN_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** - * @brief Output buffer size for FLEXCOM4. - */ -#if !defined(SAMA_SERIAL_FLEXCOM4_OUT_BUF_SIZE) || defined(__DOXYGEN__) -#define SAMA_SERIAL_FLEXCOM4_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE -#endif - -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/** - * @brief At least an UART unit is in use. - */ -#define SAMA_SERIAL_USE_UART (SAMA_SERIAL_USE_UART0 || \ - SAMA_SERIAL_USE_UART1 || \ - SAMA_SERIAL_USE_UART2 || \ - SAMA_SERIAL_USE_UART3 || \ - SAMA_SERIAL_USE_UART4) - -/** - * @brief At least an FLEXCOM unit is in use. - */ -#define SAMA_SERIAL_USE_FLEXCOM (SAMA_SERIAL_USE_FLEXCOM0 || \ - SAMA_SERIAL_USE_FLEXCOM1 || \ - SAMA_SERIAL_USE_FLEXCOM2 || \ - SAMA_SERIAL_USE_FLEXCOM3 || \ - SAMA_SERIAL_USE_FLEXCOM4) - -#if !SAMA_SERIAL_USE_UART0 && !SAMA_SERIAL_USE_UART1 && \ - !SAMA_SERIAL_USE_UART2 && !SAMA_SERIAL_USE_UART3 && \ - !SAMA_SERIAL_USE_UART4 && \ - !SAMA_SERIAL_USE_FLEXCOM0 && !SAMA_SERIAL_USE_FLEXCOM1 && \ - !SAMA_SERIAL_USE_FLEXCOM2 && !SAMA_SERIAL_USE_FLEXCOM3 && \ - !SAMA_SERIAL_USE_FLEXCOM4 -#error "SERIAL driver activated but no USART/UART peripheral assigned" -#endif - -/* Checks on allocation of UARTx units.*/ -#if SAMA_SERIAL_USE_UART0 -#if defined(SAMA_UART0_IS_USED) -#error "SD0 requires UART0 but the peripheral is already used" -#else -#define SAMA_UART0_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_UART1 -#if defined(SAMA_UART1_IS_USED) -#error "SD1 requires UART1 but the peripheral is already used" -#else -#define SAMA_UART1_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_UART2 -#if defined(SAMA_UART2_IS_USED) -#error "SD2 requires UART2 but the peripheral is already used" -#else -#define SAMA_UART2_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_UART3 -#if defined(SAMA_UART3_IS_USED) -#error "SD3 requires UART3 but the peripheral is already used" -#else -#define SAMA_UART3_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_UART4 -#if defined(SAMA_UART4_IS_USED) -#error "SD4 requires UART4 but the peripheral is already used" -#else -#define SAMA_UART4_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_FLEXCOM0 -#if defined(SAMA_FLEXCOM0_IS_USED) -#error "FSD0 requires FLEXCOM0 but the peripheral is already used" -#else -#define SAMA_FLEXCOM0_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_FLEXCOM1 -#if defined(SAMA_FLEXCOM1_IS_USED) -#error "FSD1 requires FLEXCOM1 but the peripheral is already used" -#else -#define SAMA_FLEXCOM1_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_FLEXCOM2 -#if defined(SAMA_FLEXCOM2_IS_USED) -#error "FSD2 requires FLEXCOM2 but the peripheral is already used" -#else -#define SAMA_FLEXCOM2_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_FLEXCOM3 -#if defined(SAMA_FLEXCOM3_IS_USED) -#error "FSD3 requires FLEXCOM3 but the peripheral is already used" -#else -#define SAMA_FLEXCOM3_IS_USED -#endif -#endif - -#if SAMA_SERIAL_USE_FLEXCOM4 -#if defined(SAMA_FLEXCOM4_IS_USED) -#error "FSD4 requires FLEXCOM4 but the peripheral is already used" -#else -#define SAMA_FLEXCOM4_IS_USED -#endif -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief SAMA Serial Driver configuration structure. - * @details An instance of this structure must be passed to @p sdStart() - * in order to configure and start a serial driver operations. - * @note This structure content is architecture dependent, each driver - * implementation defines its own version and the custom static - * initializers. - */ -typedef struct { - /** - * @brief Bit rate. - */ - uint32_t speed; - /* End of the mandatory fields.*/ - /** - * @brief Initialization value for the CR register. - */ - uint32_t cr; - /** - * @brief Initialization value for the MR register. - */ - uint32_t mr; -} SerialConfig; - -/** - * @brief @p SerialDriver specific data. - */ -#define _serial_driver_data \ - _base_asynchronous_channel_data \ - /* Driver state.*/ \ - sdstate_t state; \ - /* Input queue.*/ \ - input_queue_t iqueue; \ - /* Output queue.*/ \ - output_queue_t oqueue; \ - /* End of the mandatory fields.*/ \ -/* Pointer to the UART registers block.*/ \ - Uart *uart; \ - /* Pointer to the FLEXCOM registers block.*/ \ - Flexcom *flexcom; \ - /* Pointer to the UART registers block.*/ \ - Usart *usart; \ - /* Clock frequency for the associated USART/UART.*/ \ - uint32_t clock; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if SAMA_SERIAL_USE_UART0 && !defined(__DOXYGEN__) -extern SerialDriver SD0; -#endif -#if SAMA_SERIAL_USE_UART1 && !defined(__DOXYGEN__) -extern SerialDriver SD1; -#endif -#if SAMA_SERIAL_USE_UART2 && !defined(__DOXYGEN__) -extern SerialDriver SD2; -#endif -#if SAMA_SERIAL_USE_UART3 && !defined(__DOXYGEN__) -extern SerialDriver SD3; -#endif -#if SAMA_SERIAL_USE_UART4 && !defined(__DOXYGEN__) -extern SerialDriver SD4; -#endif -#if SAMA_SERIAL_USE_FLEXCOM0 && !defined(__DOXYGEN__) -extern SerialDriver FSD0; -#endif -#if SAMA_SERIAL_USE_FLEXCOM1 && !defined(__DOXYGEN__) -extern SerialDriver FSD1; -#endif -#if SAMA_SERIAL_USE_FLEXCOM2 && !defined(__DOXYGEN__) -extern SerialDriver FSD2; -#endif -#if SAMA_SERIAL_USE_FLEXCOM3 && !defined(__DOXYGEN__) -extern SerialDriver FSD3; -#endif -#if SAMA_SERIAL_USE_FLEXCOM4 && !defined(__DOXYGEN__) -extern SerialDriver FSD4; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void sd_lld_init(void); - void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); - void sd_lld_stop(SerialDriver *sdp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_SERIAL */ - -#endif /* HAL_SERIAL_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c b/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c deleted file mode 100644 index eaa53d928..000000000 --- a/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.c +++ /dev/null @@ -1,1509 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 USARTv1/hal_uart_lld.c - * @brief SAMA low level UART driver code. - * - * @addtogroup UART - * @{ - */ - -#include "hal.h" - -#if HAL_USE_UART || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -/* - * @brief NO CACHE attribute - */ -#if !defined(NO_CACHE) -#define NO_CACHE __attribute__((section (".nocache"))) -#endif -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -#if SAMA_UART_USE_UART -/** - * @brief Enable write protection on UART registers block. - * - * @param[in] uartp pointer to a UART register block - * - * @notapi - */ -#define uartEnableWP(uartp) { \ - uartp->UART_WPMR = UART_WPMR_WPKEY_PASSWD | UART_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on UART registers block. - * - * @param[in] uartp pointer to a UART register block - * - * @notapi - */ -#define uartDisableWP(uartp) { \ - uartp->UART_WPMR = UART_WPMR_WPKEY_PASSWD; \ -} -#endif - -#if SAMA_UART_USE_FLEXCOM -/** - * @brief Enable write protection on FLEXCOM registers block. - * - * @param[in] uartp pointer to a FLEXCOM register block - * - * @notapi - */ -#define uartFlexEnableWP(uartp) { \ - uartp->US_WPMR = US_WPMR_WPKEY_PASSWD | US_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on FLEXCOM registers block. - * - * @param[in] uartp pointer to a FLEXCOM register block - * - * @notapi - */ -#define uartFlexDisableWP(uartp) { \ - uartp->US_WPMR = US_WPMR_WPKEY_PASSWD; \ -} -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief UART0 UART driver identifier.*/ -#if SAMA_UART_USE_UART0 || defined(__DOXYGEN__) -UARTDriver UARTD0; -#endif - -/** @brief UART1 UART driver identifier.*/ -#if SAMA_UART_USE_UART1 || defined(__DOXYGEN__) -UARTDriver UARTD1; -#endif - -/** @brief UART2 UART driver identifier.*/ -#if SAMA_UART_USE_UART2 || defined(__DOXYGEN__) -UARTDriver UARTD2; -#endif - -/** @brief UART3 UART driver identifier.*/ -#if SAMA_UART_USE_UART3 || defined(__DOXYGEN__) -UARTDriver UARTD3; -#endif - -/** @brief UART4 UART driver identifier.*/ -#if SAMA_UART_USE_UART4 || defined(__DOXYGEN__) -UARTDriver UARTD4; -#endif - -/** @brief FLEXCOM0 UART driver identifier.*/ -#if SAMA_UART_USE_FLEXCOM0 || defined(__DOXYGEN__) -UARTDriver FUARTD0; -#endif - -/** @brief FLEXCOM1 UART driver identifier.*/ -#if SAMA_UART_USE_FLEXCOM1 || defined(__DOXYGEN__) -UARTDriver FUARTD1; -#endif - -/** @brief FLEXCOM2 UART driver identifier.*/ -#if SAMA_UART_USE_FLEXCOM2 || defined(__DOXYGEN__) -UARTDriver FUARTD2; -#endif - -/** @brief FLEXCOM3 UART driver identifier.*/ -#if SAMA_UART_USE_FLEXCOM3 || defined(__DOXYGEN__) -UARTDriver FUARTD3; -#endif - -/** @brief FLEXCOM4 UART driver identifier.*/ -#if SAMA_UART_USE_FLEXCOM4 || defined(__DOXYGEN__) -UARTDriver FUARTD4; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ -/** - * @brief Linked List view0 word aligned - * @note The descriptor is word-aligned and the two least significant - * register bits 1:0 are ignored. - */ -NO_CACHE ALIGNED_VAR(4) static lld_view0 descriptor0; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Status bits translation. - * - * @param[in] isr UART ISR register value - * - * @return The error flags. - */ -static uartflags_t translate_errors(uint32_t isr) { - uartflags_t sts = 0; - - if (isr & (UART_SR_OVRE | US_CSR_OVRE)) - sts |= UART_OVERRUN_ERROR; - if (isr & (UART_SR_PARE | US_CSR_PARE)) - sts |= UART_PARITY_ERROR; - if (isr & (UART_SR_FRAME | US_CSR_FRAME)) - sts |= UART_SR_FRAME; - return sts; -} - -/** - * @brief Puts the receiver in the UART_RX_IDLE state. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void uart_enter_rx_idle_loop(UARTDriver *uartp) { - - /* In this zone driver always cleans cache */ - cacheCleanRegion((uint32_t *) &uartp->rxbuf, sizeof(uartp->rxbuf)); - - /* Disabling BIE interrupt if rx callback is null */ - if (uartp->config->rxchar_cb == NULL) - uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CID = XDMAC_CID_BID; - - descriptor0.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDEN_UPDATED | - XDMA_UBC_NDE_FETCH_EN | XDMA_UBC_UBLEN(1); - descriptor0.mbr_nda = &descriptor0; - descriptor0.mbr_ta = (uint32_t*)&uartp->rxbuf; - - /* Configure First Descriptor Address CNCDAx */ - uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CNDA = - (((uint32_t)&descriptor0) & 0xFFFFFFFC); - /* Configure the XDMAC_CNDCx register */ - uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CNDC = - XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | XDMAC_CNDC_NDVIEW_NDV0; - - dmaChannelEnable(uartp->dmarx); -} - -/** - * @brief UART de-initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void uart_stop(UARTDriver *uartp) { - - /* Stops RX and TX DMA channels.*/ - dmaChannelDisable(uartp->dmarx); - dmaChannelDisable(uartp->dmatx); - -#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM - if (uartp->uart != NULL) -#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */ -#if SAMA_UART_USE_UART - { - Uart *u = uartp->uart; - - /* Disabling write protection */ - uartDisableWP(u); - - /* Stops UART operations.*/ - uartp->uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX; - - /* Resets UART's register */ - uartp->uart->UART_MR = 0; - - /* Enabling write protection */ - uartEnableWP(u); - } -#endif /* SAMA_UART_USE_UART */ -#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM - else if (uartp->usart != NULL) -#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */ -#if SAMA_UART_USE_FLEXCOM - { - Usart *us = uartp->usart; - - /* Disabling write protection */ - uartFlexDisableWP(us); - - /* Stops UART operations.*/ - us->US_CR = US_CR_RSTRX | US_CR_RSTTX; - - /* Resets UART's register */ - us->US_MR = 0; - - /* Disabling write protection */ - uartFlexEnableWP(us); - } -#endif /* SAMA_UART_USE_FLEXCOM */ -#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM - else { - osalDbgAssert(FALSE, "invalid state"); - } -#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */ -} - -/** - * @brief UART initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void uart_start(UARTDriver *uartp) { - - uint32_t cr; - const uint32_t tmo = uartp->config->timeout; -#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM - if (uartp->uart != NULL) -#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */ -#if SAMA_UART_USE_UART - { - Uart *u = uartp->uart; - - /* Defensive programming, starting from a clean state.*/ - uart_stop(uartp); - - /* Disabling write protection */ - uartDisableWP(u); - - /* Baud rate setting.*/ - u->UART_BRGR = UART_BRGR_CD(uartp->clock / (16 * uartp->config->speed)); - - /* Clearing pending flags */ - u->UART_CR = UART_CR_RSTSTA; - - /* Enabling interrupts */ - u->UART_IER = UART_IER_OVRE | UART_IER_FRAME | UART_IER_PARE; - - cr = UART_CR_RXEN | UART_CR_TXEN; - u->UART_CR = uartp->config->cr | cr; - u->UART_MR = uartp->config->mr; - - /* Set receive timeout and checks if it is really applied.*/ - if (tmo > 0) { - /* - * TODO: insert Function parameters check - */ - u->UART_RTOR = tmo; - } - /* Enabling write protection */ - uartEnableWP(u); - } -#endif /* SAMA_UART_USE_UART */ -#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM - else if (uartp->usart != NULL) -#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */ -#if SAMA_UART_USE_FLEXCOM - { - Usart *us = uartp->usart; - - /* Defensive programming, starting from a clean state.*/ - uart_stop(uartp); - - /* Disabling write protection */ - uartFlexDisableWP(us); - - /* Baud rate setting.*/ - us->US_BRGR = US_BRGR_CD(uartp->clock / (16 * uartp->config->speed)); - - /* Clearing pending flags */ - us->US_CR = US_CR_RSTSTA; - - /* Enabling interrupts */ - us->US_IER = US_IER_OVRE | US_IER_FRAME | US_IER_PARE; - - cr = US_CR_RXEN | US_CR_TXEN; - us->US_CR = uartp->config->cr | cr; - us->US_MR = uartp->config->mr; - - /* Set receive timeout and checks if it is really applied.*/ - if (tmo > 0) { - /* - * TODO: insert Function parameters check - */ - us->US_RTOR = tmo; - } - - /* Enabling write protection */ - uartFlexEnableWP(us); - } -#endif /* SAMA_UART_USE_FLEXCOM */ -#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM - else { - osalDbgAssert(FALSE, "invalid state"); - } -#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */ - - /* Starting the receiver idle loop.*/ - uart_enter_rx_idle_loop(uartp); -} - -/** - * @brief RX DMA common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(SAMA_UART_DMA_ERROR_HOOK) - if ((flags & (XDMAC_CIS_RBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_UART_DMA_ERROR_HOOK(uartp); - } -#else - (void)flags; -#endif - - if (uartp->rxstate == UART_RX_IDLE) { -#if (SAMA_UART_CACHE_USER_MANAGED == FALSE) - cacheInvalidateRegion((uint32_t *)&uartp->rxbuf, sizeof(uartp->rxbuf)); -#endif - /* Receiver in idle state, a callback is generated, if enabled, for each - received character and then the driver stays in the same state.*/ - _uart_rx_idle_code(uartp); - } - else { -#if (SAMA_UART_CACHE_USER_MANAGED == FALSE) - cacheInvalidateRegion(uartp->rxbufp, uartp->rxbytes); -#endif - /* Receiver in active state, a callback is generated, if enabled, after - a completed transfer.*/ - dmaChannelDisable(uartp->dmarx); - _uart_rx_complete_isr_code(uartp); - } -} - -/** - * @brief TX DMA common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & (XDMAC_CIS_WBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_UART_DMA_ERROR_HOOK(uartp); - } -#else - (void)flags; -#endif - - dmaChannelDisable(uartp->dmatx); - - /* A callback is generated, if enabled, after a completed transfer.*/ - _uart_tx1_isr_code(uartp); -} - -#if SAMA_UART_USE_UART -/** - * @brief UART common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void serve_uart_irq(UARTDriver *uartp) { - Uart *u = uartp->uart; - uint32_t imr = u->UART_IMR; - uint32_t sr; - - /* Reading and clearing status.*/ - sr = u->UART_SR; - u->UART_CR |= UART_CR_RSTSTA; - - if (sr & (UART_SR_OVRE | UART_SR_FRAME | UART_SR_PARE)) { - _uart_rx_error_isr_code(uartp, translate_errors(sr)); - } - - if ((imr & UART_IMR_TXEMPTY) && (sr & (UART_SR_TXRDY | UART_SR_TXEMPTY))) { - /* TC interrupt disabled.*/ - u->UART_IDR |= UART_IDR_TXEMPTY; - - /* End of transmission, a callback is generated.*/ - _uart_tx2_isr_code(uartp); - } -} -#endif - -#if SAMA_UART_USE_FLEXCOM -/** - * @brief UART common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void serve_uartFlex_irq(UARTDriver *uartp) { - Usart *us = uartp->usart; - uint32_t imr = us->US_IMR; - uint32_t sr; - - /* Reading and clearing status.*/ - sr = us->US_CSR; - us->US_CR |= US_CR_RSTSTA; - - if (sr & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE)) { - _uart_rx_error_isr_code(uartp, translate_errors(sr)); - } - - if ((imr & US_IMR_TXEMPTY) && (sr & (US_CSR_TXRDY | US_CSR_TXEMPTY))) { - /* TC interrupt disabled.*/ - us->US_IDR |= US_IDR_TXEMPTY; - - /* End of transmission, a callback is generated.*/ - _uart_tx2_isr_code(uartp); - } -} -#endif - - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if SAMA_UART_USE_UART0 || defined(__DOXYGEN__) -/** - * @brief UART0 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uart_irq(&UARTD0); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_UART0 */ - -#if SAMA_UART_USE_UART1 || defined(__DOXYGEN__) -/** - * @brief UART1 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uart_irq(&UARTD1); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_UART1 */ - -#if SAMA_UART_USE_UART2 || defined(__DOXYGEN__) -/** - * @brief UART2 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uart_irq(&UARTD2); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_UART2 */ - -#if SAMA_UART_USE_UART3 || defined(__DOXYGEN__) -/** - * @brief UART3 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uart_irq(&UARTD3); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_UART3 */ - -#if SAMA_UART_USE_UART4 || defined(__DOXYGEN__) -/** - * @brief UART4 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uart_irq(&UARTD4); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_UART4 */ - -#if SAMA_UART_USE_FLEXCOM0 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM0 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_irq(&FUARTD0); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_FLEXCOM0 */ - -#if SAMA_UART_USE_FLEXCOM1 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM1 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_irq(&FUARTD1); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_FLEXCOM1 */ - -#if SAMA_UART_USE_FLEXCOM2 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM2 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_irq(&FUARTD2); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_FLEXCOM2 */ - -#if SAMA_UART_USE_FLEXCOM3 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM3 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_irq(&FUARTD3); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_FLEXCOM3 */ - -#if SAMA_UART_USE_FLEXCOM4 || defined(__DOXYGEN__) -/** - * @brief FLEXCOM4 IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - serve_uartFlex_irq(&FUARTD4); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_UART_USE_FLEXCOM4 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level UART driver initialization. - * - * @notapi - */ -void uart_lld_init(void) { - -#if SAMA_UART_USE_UART0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&UARTD0); - UARTD0.uart = UART0; - UARTD0.clock = SAMA_UART0CLK; - UARTD0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_UART0_RX); - UARTD0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_UART0_TX); - UARTD0.dmarx = 0; - UARTD0.dmatx = 0; -#endif - -#if SAMA_UART_USE_UART1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&UARTD1); - UARTD1.uart = UART1; - UARTD1.clock = SAMA_UART1CLK; - UARTD1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_UART1_RX); - UARTD1.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_UART1_TX); - UARTD1.dmarx = 0; - UARTD1.dmatx = 0; -#endif - -#if SAMA_UART_USE_UART2 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART2, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&UARTD2); - UARTD2.uart = UART2; - UARTD2.clock = SAMA_UART2CLK; - UARTD2.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_UART2_RX); - UARTD2.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_UART2_TX); - UARTD2.dmarx = 0; - UARTD2.dmatx = 0; -#endif - -#if SAMA_UART_USE_UART3 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART3, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&UARTD3); - UARTD3.uart = UART3; - UARTD3.clock = SAMA_UART3CLK; - UARTD3.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_UART3_RX); - UARTD3.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_UART3_TX); - UARTD3.dmarx = 0; - UARTD3.dmatx = 0; -#endif - -#if SAMA_UART_USE_UART4 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_UART4, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&UARTD4); - UARTD4.uart = UART4; - UARTD4.clock = SAMA_UART4CLK; - UARTD4.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_UART4_RX); - UARTD4.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_UART4_TX); - UARTD4.dmarx = 0; - UARTD4.dmatx = 0; -#endif - -#if SAMA_UART_USE_FLEXCOM0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&FUARTD0); - FUARTD0.flexcom = FLEXCOM0; - FUARTD0.usart = USART0; - FUARTD0.clock = SAMA_FLEXCOM0CLK; - FUARTD0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM0_RX); - FUARTD0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM0_TX); - FUARTD0.dmarx = 0; - FUARTD0.dmatx = 0; -#endif - -#if SAMA_UART_USE_FLEXCOM1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&FUARTD1); - FUARTD1.flexcom = FLEXCOM1; - FUARTD1.usart = USART1; - FUARTD1.clock = SAMA_FLEXCOM1CLK; - FUARTD1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM1_RX); - FUARTD1.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM1_TX); - FUARTD1.dmarx = 0; - FUARTD1.dmatx = 0; -#endif - -#if SAMA_UART_USE_FLEXCOM2 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM2, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&FUARTD2); - FUARTD2.flexcom = FLEXCOM2; - FUARTD2.usart = USART2; - FUARTD2.clock = SAMA_FLEXCOM2CLK; - FUARTD2.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM2_RX); - FUARTD2.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM2_TX); - FUARTD2.dmarx = 0; - FUARTD2.dmatx = 0; -#endif - -#if SAMA_UART_USE_FLEXCOM3 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM3, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&FUARTD3); - FUARTD3.flexcom = FLEXCOM3; - FUARTD3.usart = USART3; - FUARTD3.clock = SAMA_FLEXCOM3CLK; - FUARTD3.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM3_RX); - FUARTD3.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM3_TX); - FUARTD3.dmarx = 0; - FUARTD3.dmatx = 0; -#endif - -#if SAMA_UART_USE_FLEXCOM4 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_FLEXCOM4, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - uartObjectInit(&FUARTD4); - FUARTD4.flexcom = FLEXCOM4; - FUARTD4.usart = USART4; - FUARTD4.clock = SAMA_FLEXCOM4CLK; - FUARTD4.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_PER2MEM | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF1 | - XDMAC_CC_DIF_AHB_IF0 | - XDMAC_CC_SAM_FIXED_AM | - XDMAC_CC_DAM_INCREMENTED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM4_RX); - FUARTD4.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SIXTEEN | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_BYTE | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_FLEXCOM4_TX); - FUARTD4.dmarx = 0; - FUARTD4.dmatx = 0; -#endif - -} - - -/** - * @brief Configures and activates the UART peripheral. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @notapi - */ -void uart_lld_start(UARTDriver *uartp) { - - if (uartp->state == UART_STOP) { -#if SAMA_UART_USE_UART0 - if (&UARTD0 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - pmcEnableUART0(); - aicSetSourcePriority(ID_UART0, SAMA_UART_UART0_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART0, SAMA_UART0_HANDLER); - aicEnableInt(ID_UART0); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->uart->UART_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_UART1 - if (&UARTD1 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - pmcEnableUART1(); - aicSetSourcePriority(ID_UART1, SAMA_UART_UART1_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART1, SAMA_UART1_HANDLER); - aicEnableInt(ID_UART1); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->uart->UART_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_UART2 - if (&UARTD2 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART2_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART2_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - pmcEnableUART2(); - aicSetSourcePriority(ID_UART2, SAMA_UART_UART2_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART2, SAMA_UART2_HANDLER); - aicEnableInt(ID_UART2); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->uart->UART_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_UART3 - if (&UARTD3 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART3_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART3_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - pmcEnableUART3(); - aicSetSourcePriority(ID_UART3, SAMA_UART_UART3_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART3, SAMA_UART3_HANDLER); - aicEnableInt(ID_UART3); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->uart->UART_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_UART4 - if (&UARTD4 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART4_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART4_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - pmcEnableUART4(); - aicSetSourcePriority(ID_UART4, SAMA_UART_UART4_IRQ_PRIORITY); - aicSetSourceHandler(ID_UART4, SAMA_UART4_HANDLER); - aicEnableInt(ID_UART4); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->uart->UART_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_FLEXCOM0 - if (&FUARTD0 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - /* Enabling USART on FLEXCOM */ - uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART; - pmcEnableFLEXCOM0(); - aicSetSourcePriority(ID_USART0, SAMA_UART_FLEXCOM0_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART0, SAMA_UART_FLEXCOM0_HANDLER); - aicEnableInt(ID_USART0); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_FLEXCOM1 - if (&FUARTD1 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - /* Enabling USART on FLEXCOM */ - uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART; - pmcEnableFLEXCOM1(); - aicSetSourcePriority(ID_USART1, SAMA_UART_FLEXCOM1_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART1, SAMA_UART_FLEXCOM1_HANDLER); - aicEnableInt(ID_USART1); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_FLEXCOM2 - if (&FUARTD2 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - /* Enabling USART on FLEXCOM */ - uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART; - pmcEnableFLEXCOM2(); - aicSetSourcePriority(ID_USART2, SAMA_UART_FLEXCOM2_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART2, SAMA_UART_FLEXCOM2_HANDLER); - aicEnableInt(ID_USART2); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_FLEXCOM3 - if (&FUARTD3 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - /* Enabling USART on FLEXCOM */ - uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART; - pmcEnableFLEXCOM3(); - aicSetSourcePriority(ID_USART3, SAMA_UART_FLEXCOM3_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART3, SAMA_UART_FLEXCOM3_HANDLER); - aicEnableInt(ID_USART3); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -#if SAMA_UART_USE_FLEXCOM4 - if (&FUARTD4 == uartp) { - uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_rx_end_irq, - (void *)uartp); - - uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)uart_lld_serve_tx_end_irq, - (void *)uartp); - /* Enabling USART on FLEXCOM */ - uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART; - pmcEnableFLEXCOM4(); - aicSetSourcePriority(ID_USART4, SAMA_UART_FLEXCOM4_IRQ_PRIORITY); - aicSetSourceHandler(ID_USART4, SAMA_UART_FLEXCOM4_HANDLER); - aicEnableInt(ID_USART4); - - /* Configuring destination and mode of txdma channel*/ - dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR); - dmaChannelSetMode(uartp->dmatx, uartp->txdmamode); - - /* Configuring source and mode of rxdma channel*/ - dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - } -#endif - -/* - * TODO: Configure DMA for bit > 9 - */ - - uartp->rxbuf = 0; - } - - uartp->rxstate = UART_RX_IDLE; - uartp->txstate = UART_TX_IDLE; - uart_start(uartp); -} - -/** - * @brief Deactivates the UART peripheral. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @notapi - */ -void uart_lld_stop(UARTDriver *uartp) { - - if (uartp->state == UART_READY) { - uart_stop(uartp); - dmaChannelRelease(uartp->dmarx); - dmaChannelRelease(uartp->dmatx); - -#if SAMA_UART_USE_UART0 - if (&UARTD0 == uartp) { - pmcDisableUART0(); - return; - } -#endif - -#if SAMA_UART_USE_UART1 - if (&UARTD1 == uartp) { - pmcDisableUART1(); - return; - } -#endif - -#if SAMA_UART_USE_UART2 - if (&UARTD2 == uartp) { - pmcDisableUART2(); - return; - } -#endif - -#if SAMA_UART_USE_UART3 - if (&UARTD3 == uartp) { - pmcDisableUART3(); - return; - } -#endif - -#if SAMA_UART_USE_UART4 - if (&UARTD4 == uartp) { - pmcDisableUART4(); - return; - } -#endif - -#if SAMA_UART_USE_FLEXCOM0 - if (&FUARTD0 == uartp) { - pmcDisableFLEXCOM0(); - return; - } -#endif - -#if SAMA_UART_USE_FLEXCOM1 - if (&FUARTD1 == uartp) { - pmcDisableFLEXCOM1(); - return; - } -#endif - -#if SAMA_UART_USE_FLEXCOM2 - if (&FUARTD2 == uartp) { - pmcDisableFLEXCOM2(); - return; - } -#endif - -#if SAMA_UART_USE_FLEXCOM3 - if (&FUARTD3 == uartp) { - pmcDisableFLEXCOM3(); - return; - } -#endif - -#if SAMA_UART_USE_FLEXCOM4 - if (&FUARTD4 == uartp) { - pmcDisableFLEXCOM4(); - return; - } -#endif - } - uartp->txbufp = NULL; - uartp->rxbufp = NULL; - uartp->rxbytes = 0; -} - -/** - * @brief Starts a transmission on the UART peripheral. - * @note The buffers are organized as uint8_t arrays for data sizes below - * or equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] n number of data frames to send - * @param[in] txbuf the pointer to the transmit buffer - * - * @notapi - */ -void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { - - uartp->txbufp = txbuf; - -#if (SAMA_UART_CACHE_USER_MANAGED == FALSE) - - osalDbgAssert(!((uint32_t) txbuf & (L1_CACHE_BYTES - 1)), "address not cache aligned"); - -#if 0 - osalDbgAssert(!(n & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - /* Cache is enabled */ - cacheCleanRegion((uint8_t *) txbuf, n); -#endif /* SAMA_UART_CACHE_USER_MANAGED */ - - /* TX DMA channel preparation.*/ - dmaChannelSetSource(uartp->dmatx, txbuf); - dmaChannelSetTransactionSize(uartp->dmatx, n); - - /* Starting transfer.*/ - dmaChannelEnable(uartp->dmatx); - - /* Only enable TC interrupt if there's a callback attached to it. - Also we need to clear TC flag which could be set before. */ - if (uartp->config->txend2_cb != NULL) { -#if SAMA_UART_USE_UART - if (uartp->uart != NULL) - uartp->uart->UART_IER = UART_IER_TXEMPTY; -#endif -#if SAMA_UART_USE_FLEXCOM - if (uartp->usart != NULL) - uartp->usart->US_IER = US_IER_TXEMPTY; -#endif - } -} - -/** - * @brief Stops any ongoing transmission. - * @note Stopping a transmission also suppresses the transmission callbacks. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @return The number of data frames not transmitted by the - * stopped transmit operation. - * - * @notapi - */ -size_t uart_lld_stop_send(UARTDriver *uartp) { - - uartp->txbufp = NULL; - - dmaChannelDisable(uartp->dmatx); - - return dmaChannelGetTransactionSize(uartp->dmatx); -} - -/** - * @brief Starts a receive operation on the UART peripheral. - * @note The buffers are organized as uint8_t arrays for data sizes below - * or equal to 8 bits else it is organized as uint16_t arrays. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] n number of data frames to send - * @param[out] rxbuf the pointer to the receive buffer - * - * @notapi - */ -void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { - - uartp->rxbufp = rxbuf; - uartp->rxbytes = n; - -#if (SAMA_UART_CACHE_USER_MANAGED == FALSE) - - osalDbgAssert(!((uint32_t) rxbuf & (L1_CACHE_BYTES - 1)), "address not cache aligned"); - -#if 0 - osalDbgAssert(!(n & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - /* - * If size is not multiple of cache line, clean cache region is required. - * TODO: remove when size assert works - */ - if (n & (L1_CACHE_BYTES - 1)) { - cacheCleanRegion((uint8_t *) rxbuf, n); - } -#endif /* SAMA_UART_CACHE_USER_MANAGED */ - - /* Stopping previous activity (idle state).*/ - dmaChannelDisable(uartp->dmarx); - - /* Enabling BIE interrupt if disabled */ - if ((uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CIM & XDMAC_CIM_BIM) == 0) { - uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CIE = XDMAC_CIE_BIE; - } - - /* Resetting the XDMAC_CNCDAx */ - uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CNDA = 0; - /* resetting the XDMAC_CNDCx register */ - uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CNDC = 0; - - /* RX DMA channel preparation.*/ -#if SAMA_UART_USE_UART - if (uartp->uart != NULL) - dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR); -#endif -#if SAMA_UART_USE_FLEXCOM - if (uartp->usart != NULL) - dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR); -#endif - dmaChannelSetDestination(uartp->dmarx, rxbuf); - dmaChannelSetTransactionSize(uartp->dmarx, n); - dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode); - - /* Starting transfer.*/ - dmaChannelEnable(uartp->dmarx); -} - -/** - * @brief Stops any ongoing receive operation. - * @note Stopping a receive operation also suppresses the receive callbacks. - * - * @param[in] uartp pointer to the @p UARTDriver object - * - * @return The number of data frames not received by the - * stopped receive operation. - * - * @notapi - */ -size_t uart_lld_stop_receive(UARTDriver *uartp) { - - size_t n; - - uartp->rxbufp = NULL; - uartp->rxbytes = 0; - - dmaChannelDisable(uartp->dmarx); - n = dmaChannelGetTransactionSize(uartp->dmarx); - uart_enter_rx_idle_loop(uartp); - - return n; -} - -#endif /* HAL_USE_UART */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.h b/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.h deleted file mode 100644 index 1f299e650..000000000 --- a/os/hal/ports/SAMA/LLD/USARTv1/hal_uart_lld.h +++ /dev/null @@ -1,656 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 USARTv1/hal_uart_lld.h - * @brief SAMA low level UART driver header. - * - * @addtogroup UART - * @{ - */ - -#ifndef HAL_UART_LLD_H -#define HAL_UART_LLD_H - -#if HAL_USE_UART || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief UART driver on UART0 enable switch. - * @details If set to @p TRUE the support for UART0 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_UART0) || defined(__DOXYGEN__) -#define SAMA_UART_USE_UART0 FALSE -#endif - -/** - * @brief UART driver on UART1 enable switch. - * @details If set to @p TRUE the support for UART1 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_UART1) || defined(__DOXYGEN__) -#define SAMA_UART_USE_UART1 FALSE -#endif - -/** - * @brief UART driver on UART2 enable switch. - * @details If set to @p TRUE the support for UART2 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_UART2) || defined(__DOXYGEN__) -#define SAMA_UART_USE_UART2 FALSE -#endif - -/** - * @brief UART driver on UART3 enable switch. - * @details If set to @p TRUE the support for UART4 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_UART3) || defined(__DOXYGEN__) -#define SAMA_UART_USE_UART3 FALSE -#endif - -/** - * @brief UART driver on UART4 enable switch. - * @details If set to @p TRUE the support for UART4 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_UART4) || defined(__DOXYGEN__) -#define SAMA_UART_USE_UART4 FALSE -#endif - -/** - * @brief UART driver on FLEXCOM0 enable switch. - * @details If set to @p TRUE the support for FLEXCOM0 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_FLEXCOM0) || defined(__DOXYGEN__) -#define SAMA_UART_USE_FLEXCOM0 FALSE -#endif - -/** - * @brief UART driver on FLEXCOM1 enable switch. - * @details If set to @p TRUE the support for FLEXCOM1 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_FLEXCOM1) || defined(__DOXYGEN__) -#define SAMA_UART_USE_FLEXCOM1 FALSE -#endif - -/** - * @brief UART driver on FLEXCOM2 enable switch. - * @details If set to @p TRUE the support for FLEXCOM2 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_FLEXCOM2) || defined(__DOXYGEN__) -#define SAMA_UART_USE_FLEXCOM2 FALSE -#endif - -/** - * @brief UART driver on FLEXCOM3 enable switch. - * @details If set to @p TRUE the support for FLEXCOM3 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_FLEXCOM3) || defined(__DOXYGEN__) -#define SAMA_UART_USE_FLEXCOM3 FALSE -#endif - -/** - * @brief UART driver on FLEXCOM4 enable switch. - * @details If set to @p TRUE the support for FLEXCOM4 is included. - * @note The default is @p FALSE. - */ -#if !defined(SAMA_UART_USE_FLEXCOM4) || defined(__DOXYGEN__) -#define SAMA_UART_USE_FLEXCOM4 FALSE -#endif - -/** - * @brief UART0 interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART0_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART1 interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART1_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART2 interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART2_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART3 interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART3_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART4 interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART4_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM0 interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM0_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM1 interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM1_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM2 interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM2_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM3 interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM3_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM4 interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM4_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM4_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART0 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART0_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART1 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART1_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART2 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART2_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART3 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART3_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART4 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_UART4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_UART4_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM0 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM1 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM2 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM3 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief FLEXCOM4 DMA interrupt priority level setting. - */ -#if !defined(SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY 4 -#endif - -/** - * @brief UART DMA error hook. - * @note The default action for DMA errors is a system halt because DMA - * error can only happen because programming errors. - */ -#if !defined(SAMA_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define SAMA_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") -#endif - -/** - * @brief UART cache managing. - */ -#if !defined(SAMA_UART_CACHE_USER_MANAGED) || defined(__DOXYGEN__) -#define SAMA_UART_CACHE_USER_MANAGED FALSE -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/** - * @brief At least an UART unit is in use. - */ -#define SAMA_UART_USE_UART (SAMA_UART_USE_UART0 || \ - SAMA_UART_USE_UART1 || \ - SAMA_UART_USE_UART2 || \ - SAMA_UART_USE_UART3 || \ - SAMA_UART_USE_UART4) - -/** - * @brief At least an FLEXCOM unit is in use. - */ -#define SAMA_UART_USE_FLEXCOM (SAMA_UART_USE_FLEXCOM0 || \ - SAMA_UART_USE_FLEXCOM1 || \ - SAMA_UART_USE_FLEXCOM2 || \ - SAMA_UART_USE_FLEXCOM3 || \ - SAMA_UART_USE_FLEXCOM4) - - -#if !SAMA_UART_USE_UART0 && !SAMA_UART_USE_UART1 && \ - !SAMA_UART_USE_UART2 && !SAMA_UART_USE_UART3 && \ - !SAMA_UART_USE_UART4 && \ - !SAMA_UART_USE_FLEXCOM0 && !SAMA_UART_USE_FLEXCOM1 && \ - !SAMA_UART_USE_FLEXCOM2 && !SAMA_UART_USE_FLEXCOM3 && \ - !SAMA_UART_USE_FLEXCOM4 -#error "UART driver activated but no USART/UART peripheral assigned" -#endif - -/* Checks on allocation of UARTx units.*/ -#if SAMA_UART_USE_UART0 -#if defined(SAMA_UART0_IS_USED) -#error "UARTD0 requires UART0 but the peripheral is already used" -#else -#define SAMA_UART0_IS_USED -#endif -#endif - -#if SAMA_UART_USE_UART1 -#if defined(SAMA_UART1_IS_USED) -#error "UARTD1 requires UART1 but the peripheral is already used" -#else -#define SAMA_UART1_IS_USED -#endif -#endif - -#if SAMA_UART_USE_UART2 -#if defined(SAMA_UART2_IS_USED) -#error "UARTD2 requires UART2 but the peripheral is already used" -#else -#define SAMA_UART2_IS_USED -#endif -#endif - -#if SAMA_UART_USE_UART3 -#if defined(SAMA_UART3_IS_USED) -#error "UARTD3 requires UART3 but the peripheral is already used" -#else -#define SAMA_UART3_IS_USED -#endif -#endif - -#if SAMA_UART_USE_UART4 -#if defined(SAMA_UART4_IS_USED) -#error "UARTD4 requires UART4 but the peripheral is already used" -#else -#define SAMA_UART4_IS_USED -#endif -#endif - -#if SAMA_UART_USE_FLEXCOM0 -#if defined(SAMA_FLEXCOM0_IS_USED) -#error "FUARTD0 requires FLEXCOM0 but the peripheral is already used" -#else -#define SAMA_FLEXCOM0_IS_USED -#endif -#endif - -#if SAMA_UART_USE_FLEXCOM1 -#if defined(SAMA_FLEXCOM1_IS_USED) -#error "FUARTD1 requires FLEXCOM1 but the peripheral is already used" -#else -#define SAMA_FLEXCOM1_IS_USED -#endif -#endif - -#if SAMA_UART_USE_FLEXCOM2 -#if defined(SAMA_FLEXCOM2_IS_USED) -#error "FUARTD2 requires FLEXCOM2 but the peripheral is already used" -#else -#define SAMA_FLEXCOM2_IS_USED -#endif -#endif - -#if SAMA_UART_USE_FLEXCOM3 -#if defined(SAMA_FLEXCOM3_IS_USED) -#error "FUARTD3 requires FLEXCOM3 but the peripheral is already used" -#else -#define SAMA_FLEXCOM3_IS_USED -#endif -#endif - -#if SAMA_UART_USE_FLEXCOM4 -#if defined(SAMA_FLEXCOM4_IS_USED) -#error "FUARTD4 requires FLEXCOM4 but the peripheral is already used" -#else -#define SAMA_FLEXCOM4_IS_USED -#endif -#endif - -#if !defined(SAMA_DMA_REQUIRED) -#define SAMA_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief UART driver condition flags type. - */ -typedef uint32_t uartflags_t; - -/** - * @brief Structure representing an UART driver. - */ -typedef struct UARTDriver UARTDriver; - -/** - * @brief Generic UART notification callback type. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -typedef void (*uartcb_t)(UARTDriver *uartp); - -/** - * @brief Character received UART notification callback type. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] c received character - */ -typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c); - -/** - * @brief Receive error UART notification callback type. - * - * @param[in] uartp pointer to the @p UARTDriver object - * @param[in] e receive error mask - */ -typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief End of transmission buffer callback. - */ - uartcb_t txend1_cb; - /** - * @brief Physical end of transmission callback. - */ - uartcb_t txend2_cb; - /** - * @brief Receive buffer filled callback. - */ - uartcb_t rxend_cb; - /** - * @brief Character received while out if the @p UART_RECEIVE state. - */ - uartccb_t rxchar_cb; - /** - * @brief Receive error callback. - */ - uartecb_t rxerr_cb; - /* End of the mandatory fields.*/ - /** - * @brief Receiver timeout callback. - * @details Handles both idle and timeout interrupts depending on configured - * flags in CR registers and supported hardware features. - */ - uartcb_t timeout_cb; - /** - * @brief Receiver timeout value in terms of number of bit duration. - * @details Set it to 0 when you want to handle idle interrupt instead of - * hardware timeout. - */ - uint32_t timeout; - /** - * @brief Bit rate. - */ - uint32_t speed; - /** - * @brief Initialization value for the CR register. - */ - uint32_t cr; - /** - * @brief Initialization value for the MR register. - */ - uint32_t mr; -} UARTConfig; - -/** - * @brief Structure representing an UART driver. - */ -struct UARTDriver { - /** - * @brief Driver state. - */ - uartstate_t state; - /** - * @brief Transmitter state. - */ - uarttxstate_t txstate; - /** - * @brief Receiver state. - */ - uartrxstate_t rxstate; - /** - * @brief Current configuration data. - */ - const UARTConfig *config; -#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__) - /** - * @brief Synchronization flag for transmit operations. - */ - bool early; - /** - * @brief Waiting thread on RX. - */ - thread_reference_t threadrx; - /** - * @brief Waiting thread on TX. - */ - thread_reference_t threadtx; -#endif /* UART_USE_WAIT */ -#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) - /** - * @brief Mutex protecting the peripheral. - */ - mutex_t mutex; -#endif /* UART_USE_MUTUAL_EXCLUSION */ -#if defined(UART_DRIVER_EXT_FIELDS) - UART_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ -#if SAMA_UART_USE_UART - /** - * @brief Pointer to the UART registers block. - */ - Uart *uart; -#endif -#if SAMA_UART_USE_FLEXCOM - /* Pointer to the FLEXCOM registers block.*/ - Flexcom *flexcom; - /* Pointer to the USART registers block.*/ - Usart *usart; -#endif - /** - * @brief Clock frequency for the associated USART/UART. - */ - uint32_t clock; - /** - * @brief DMA mode bit mask. - */ - uint32_t rxdmamode; - /** - * @brief DMA mode bit mask. - */ - uint32_t txdmamode; - /** - * @brief Receive DMA channel. - */ - sama_dma_channel_t *dmarx; - /** - * @brief Transmit DMA channel. - */ - sama_dma_channel_t *dmatx; - /** - * @brief Default receive buffer while into @p UART_RX_IDLE state. - */ - CACHE_ALIGNED - volatile uint16_t rxbuf; - /** - * @brief Pointer to the TX buffer location. - */ - const uint8_t *txbufp; - /** - * @brief Pointer to the RX buffer location. - */ - uint8_t *rxbufp; - /** - * @brief Number of bytes in RX phase. - */ - size_t rxbytes; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if SAMA_UART_USE_UART0 && !defined(__DOXYGEN__) -extern UARTDriver UARTD0; -#endif - -#if SAMA_UART_USE_UART1 && !defined(__DOXYGEN__) -extern UARTDriver UARTD1; -#endif - -#if SAMA_UART_USE_UART2 && !defined(__DOXYGEN__) -extern UARTDriver UARTD2; -#endif - -#if SAMA_UART_USE_UART3 && !defined(__DOXYGEN__) -extern UARTDriver UARTD3; -#endif - -#if SAMA_UART_USE_UART4 && !defined(__DOXYGEN__) -extern UARTDriver UARTD4; -#endif - -#if SAMA_UART_USE_FLEXCOM0 && !defined(__DOXYGEN__) -extern UARTDriver FUARTD0; -#endif - -#if SAMA_UART_USE_FLEXCOM1 && !defined(__DOXYGEN__) -extern UARTDriver FUARTD1; -#endif - -#if SAMA_UART_USE_FLEXCOM2 && !defined(__DOXYGEN__) -extern UARTDriver FUARTD2; -#endif - -#if SAMA_UART_USE_FLEXCOM3 && !defined(__DOXYGEN__) -extern UARTDriver FUARTD3; -#endif - -#if SAMA_UART_USE_FLEXCOM4 && !defined(__DOXYGEN__) -extern UARTDriver FUARTD4; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void uart_lld_init(void); - void uart_lld_start(UARTDriver *uartp); - void uart_lld_stop(UARTDriver *uartp); - void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf); - size_t uart_lld_stop_send(UARTDriver *uartp); - void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf); - size_t uart_lld_stop_receive(UARTDriver *uartp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_UART */ - -#endif /* HAL_UART_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/xWDGv1/driver.mk b/os/hal/ports/SAMA/LLD/xWDGv1/driver.mk deleted file mode 100644 index 797b95112..000000000 --- a/os/hal/ports/SAMA/LLD/xWDGv1/driver.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(USE_SMART_BUILD),yes) -ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),) -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c -endif -else -PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c -endif - -PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/xWDGv1 diff --git a/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c b/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c deleted file mode 100644 index e7c274e8c..000000000 --- a/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 WDGv1/hal_wdg_lld.c - * @brief WDG Driver subsystem low level driver source. - * - * @addtogroup WDG - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -/** - * @brief WDG driver identifier. - */ -WDGDriver WDGD0; - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Local function that computes the period - * for WDT_MR_WDV and WDT_MR_VDD registers. - * - * @param[in] period period to be computed. - * - * @notapi - */ -static uint32_t wdt_compute_period(uint32_t period) { - - uint32_t value; - value = period * (SAMA_SLOW_CLK >> 7) / 1000; - if (value > 0xfff) - value = 0xfff; - - return value; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ -/** - * @brief WDG IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_WDG_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - /* Read status register. */ - uint32_t sr = WDT->WDT_SR; - - if (WDGD0.config->callback != NULL) { - if (sr & WDT_SR_WDERR) { - WDGD0.config->callback(&WDGD0, WDG_ERROR); - } - - else - WDGD0.config->callback(&WDGD0, WDG_UNDERFLOW); - } - - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level WDG driver initialization. - * - * @notapi - */ -void wdg_lld_init(void) { - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_WDT, SECURE_PER); -#endif - - WDGD0.state = WDG_STOP; - WDGD0.wdg = WDT; -} - -/** - * @brief Configures and activates the WDT peripheral. - * - * @param[in] wdgp pointer to the @p WDGDriver object - * - * @notapi - */ -void wdg_lld_start(WDGDriver *wdgp) { - - (void) wdgp; - - /* Read status register. */ - WDT->WDT_SR; - - /* Write configuration */ - WDT->WDT_MR = (wdgp->config->mode & ~(WDT_MR_WDDIS | WDT_MR_WDD_Msk | WDT_MR_WDV_Msk)) | - WDT_MR_WDV(wdt_compute_period(wdgp->config->counter)) | - WDT_MR_WDD(wdt_compute_period(wdgp->config->delta)); - - aicSetSourcePriority(ID_WDT, SAMA_WDG_IRQ_PRIORITY); - aicSetSourceHandler(ID_WDT, SAMA_WDG_HANDLER); - aicEnableInt(ID_WDT); -} - -/** - * @brief Deactivates the WDG peripheral. - * - * @param[in] wdgp pointer to the @p WDGDriver object - * - * @notapi - */ -void wdg_lld_stop(WDGDriver *wdgp) { - - (void) wdgp; - WDT->WDT_MR = WDT_MR_WDDIS; -} - -/** - * @brief Reloads the WDG counter. - * - * @param[in] wdgp pointer to the @p WDGDriver object - * - * @notapi - */ -void wdg_lld_reset(WDGDriver * wdgp) { - - (void) wdgp; - WDT->WDT_CR = WDT_CR_KEY_PASSWD | WDT_CR_WDRSTT; -} - -#endif /* HAL_USE_WDG == TRUE */ - -/** @} */ diff --git a/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.h b/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.h deleted file mode 100644 index 0904c55fb..000000000 --- a/os/hal/ports/SAMA/LLD/xWDGv1/hal_wdg_lld.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 WDGv1/hal_wdg_lld.h - * @brief WDG Driver subsystem low level driver header. - * - * @addtogroup WDG - * @{ - */ - -#ifndef HAL_WDG_LLD_H -#define HAL_WDG_LLD_H - -#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ -/** - * @name Configuration options - * @{ - */ -/* - * WDG driver system settings. - */ -#define SAMA_WDG_IRQ_PRIORITY 4 -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ -/** - * @brief Type of an WDG event. - */ -typedef enum { - WDG_ERROR = 0, /** Watchdog fault error. */ - WDG_UNDERFLOW = 1 /** Watchdog underflow error. */ -} wdgevent_t; - -/** - * @brief Type of a structure representing an WDG driver. - */ -typedef struct WDGDriver WDGDriver; - -/** - * @brief Type of a generic WDG callback. - */ -typedef void (*wdgcb_t)(WDGDriver *wdgp, wdgevent_t event); - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief Callback pointer. - */ - wdgcb_t callback; - /** - * @brief Configuration of the WDT modes. - */ - uint32_t mode; - /** - * @brief Configuration of the WDT counter. - */ - uint32_t counter; - /** - * @brief Configuration of the WDT delta. - */ - uint32_t delta; -} WDGConfig; - -/** - * @brief Structure representing an WDG driver. - */ -struct WDGDriver { - /** - * @brief Driver state. - */ - wdgstate_t state; - /** - * @brief Current configuration data. - */ - const WDGConfig *config; - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the WDT registers block. - */ - Wdt *wdg; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern WDGDriver WDGD0; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void wdg_lld_init(void); - void wdg_lld_start(WDGDriver *wdgp); - void wdg_lld_stop(WDGDriver *wdgp); - void wdg_lld_reset(WDGDriver *wdgp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_WDG == TRUE */ - -#endif /* HAL_WDG_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c deleted file mode 100644 index ad422f265..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c +++ /dev/null @@ -1,1762 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_crypto_lld.c - * @brief PLATFORM cryptographic subsystem low level driver source. - * - * @addtogroup CRYPTO - * @{ - */ -#include -#include "hal.h" - -#if HAL_USE_CRY || defined(__DOXYGEN__) - -#include "sama_crypto_lld.h" -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - - -/** @brief CRY1 driver identifier.*/ -#if PLATFORM_CRY_USE_CRY1 || defined(__DOXYGEN__) -CRYDriver CRYD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level crypto driver initialization. - * - * @notapi - */ -void cry_lld_init(void) { -#if PLATFORM_CRY_USE_CRY1 == TRUE - cryObjectInit(&CRYD1); - samaCryptoDriverInit(&CRYD1); -#endif -} - - -/** - * @brief Configures and activates the crypto peripheral. - * - * @param[in] cryp pointer to the @p CRYDriver object - * - * @notapi - */ -void cry_lld_start(CRYDriver *cryp) { - - if (cryp->state == CRY_STOP) { - //clear key - for (size_t i=0;ikey0_buffer[i] = 0; - } - -#if PLATFORM_CRY_USE_CRY1 - if (&CRYD1 == cryp) { - samaCryptoDriverStart(&CRYD1); - } -#endif /* PLATFORM_CRY_USE_CRY1 */ - } -} - -/** - * @brief Deactivates the crypto peripheral. - * - * @param[in] cryp pointer to the @p CRYDriver object - * - * @notapi - */ -void cry_lld_stop(CRYDriver *cryp) { - - if (cryp->state == CRY_READY) { -#if PLATFORM_CRY_USE_CRY1 - if (&CRYD1 == cryp) { - samaCryptoDriverStop(&CRYD1); - } -#endif /* PLATFORM_CRY_USE_CRY1 */ - - } -} - -/** - * @brief Initializes the transient key for a specific algorithm. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] algorithm the algorithm identifier - * @param[in] size key size in bytes - * @param[in] keyp pointer to the key data - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the specified algorithm is unknown or - * unsupported. - * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid. - * - * @notapi - */ -cryerror_t cry_lld_loadkey(CRYDriver *cryp, - cryalgorithm_t algorithm, - size_t size, - const uint8_t *keyp) { - - - - uint8_t *p = (uint8_t *)cryp->key0_buffer; - - (void)algorithm; - - - if (size <= HAL_CRY_MAX_KEY_SIZE) - { - osalMutexLock(&cryp->mutex); - //clear key - for (size_t i=0;ikey0_buffer[i] = 0; - } - - for (size_t i=0;imutex); - } - else - { - return CRY_ERR_INV_KEY_SIZE; - } - - return CRY_NOERROR; - -} - -/** - * @brief Encryption of a single block using AES. - * @note The implementation of this function must guarantee that it can - * be called from any context. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out) { - - - cryerror_t ret = CRY_NOERROR; - aesparams params; - - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - params.encrypt = 1; - params.block_size = 16; - params.mode = 0; - params.iv = NULL; - - - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, 16); - - - return ret; -} - -/** - * @brief Decryption of a single block using AES. - * @note The implementation of this function must guarantee that it can - * be called from any context. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] in buffer containing the input cyphertext - * @param[out] out buffer for the output plaintext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out) { - - - cryerror_t ret = CRY_NOERROR; - aesparams params; - - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - params.encrypt = 0; - params.block_size = 16; - params.mode = 0; - params.iv = NULL; - - - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, 16); - - - return ret; -} - -/** - * @brief Encryption operation using AES-ECB. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of the selected key size - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - params.encrypt = 1; - params.block_size = 16; - params.mode = AES_MR_OPMOD_ECB; - params.iv = NULL; - - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - return ret; -} - -/** - * @brief Decryption operation using AES-ECB. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of the selected key size - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - params.encrypt = 0; - params.block_size = 16; - params.mode = AES_MR_OPMOD_ECB; - - - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - - return ret; -} - -/** - * @brief Encryption operation using AES-CBC. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of the selected key size - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 128 bits initial vector - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES() - ; - } - params.encrypt = 1; - params.block_size = 16; - params.mode = AES_MR_OPMOD_CBC; - params.iv = iv; - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - - return ret; -} - -/** - * @brief Decryption operation using AES-CBC. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of the selected key size - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 128 bits initial vector - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES() - ; - } - - params.encrypt = 0; - params.block_size = 16; - params.mode = AES_MR_OPMOD_CBC; - params.iv = iv; - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - - return ret; -} - -/** - * @brief Encryption operation using AES-CFB. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of the selected key size - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 128 bits initial vector - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES() - ; - } - params.encrypt = 1; - params.block_size = 16; - switch (cryp->config->cfbs) { - case AES_CFBS_128: - params.block_size = 16; - break; - case AES_CFBS_64: - params.block_size = 8; - break; - case AES_CFBS_32: - params.block_size = 4; - break; - case AES_CFBS_16: - params.block_size = 2; - break; - case AES_CFBS_8: - params.block_size = 1; - break; - } - params.mode = AES_MR_OPMOD_CFB; - params.iv = iv; - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - return ret; -} - -/** - * @brief Decryption operation using AES-CFB. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of the selected key size - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 128 bits initial vector - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES() - ; - } - - params.encrypt = 0; - params.block_size = 16; - switch (cryp->config->cfbs) { - case AES_CFBS_128: - params.block_size = 16; - break; - case AES_CFBS_64: - params.block_size = 8; - break; - case AES_CFBS_32: - params.block_size = 4; - break; - case AES_CFBS_16: - params.block_size = 2; - break; - case AES_CFBS_8: - params.block_size = 1; - break; - } - params.mode = AES_MR_OPMOD_CFB; - params.iv = iv; - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - - return ret; -} - -/** - * @brief Encryption operation using AES-CTR. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of 16 - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 128 bits initial vector + counter, it contains - * a 96 bits IV and a 32 bits counter - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - - if(key_id != 0 ) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - params.encrypt = 1; - params.block_size = 16; - params.mode = AES_MR_OPMOD_CTR; - params.iv = iv; - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - - - return ret; -} - -/** - * @brief Decryption operation using AES-CTR. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of 16 - * @param[in] in buffer containing the input cyphertext - * @param[out] out buffer for the output plaintext - * @param[in] iv 128 bits initial vector + counter, it contains - * a 96 bits IV and a 32 bits counter - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - aesparams params; - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - params.encrypt = 0; - params.block_size = 16; - params.mode = AES_MR_OPMOD_CTR; - params.iv = iv; - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); - else - ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); - - return ret; -} - -/** - * @brief Encryption operation using AES-GCM. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the text buffers, this number must be a - * multiple of 16 - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 128 bits initial vector + counter, it contains - * a 96 bits IV and a 32 bits counter - * @param[in] aadsize size of the authentication data, this number - * must be a multiple of 16 - * @param[in] aad buffer containing the authentication data - * @param[in] authtag 128 bits buffer for the generated authentication - * tag - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv, - size_t aadsize, - const uint8_t *aad, - uint8_t *authtag) { - - cryerror_t ret = CRY_NOERROR; - cgmcontext ctx; - - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - ctx.params.encrypt = 1; - ctx.params.block_size = 16; - ctx.params.mode = AES_MR_OPMOD_GCM; - ctx.params.iv = iv; - - ctx.in = (uint8_t *)in; - ctx.out = out; - ctx.c_size = size; - ctx.aadsize = aadsize; - ctx.aad = (uint8_t *)aad; - ctx.authtag = authtag; - - - - ret = sama_gcm_lld_process(cryp, &ctx); - - - return ret; - -} - -/** - * @brief Decryption operation using AES-GCM. - * @note The function operates on data buffers whose lenght is a multiple - * of an AES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the text buffers, this number must be a - * multiple of 16 - * @param[in] in buffer for the output cyphertext - * @param[out] out buffer containing the input plaintext - * @param[in] iv 128 bits initial vector + counter, it contains - * a 96 bits IV and a 32 bits counter - * @param[in] aadsize size of the authentication data, this number - * must be a multiple of 16 - * @param[in] aad buffer containing the authentication data - * @param[in] authtag 128 bits buffer for the generated authentication - * tag - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv, - size_t aadsize, - const uint8_t *aad, - uint8_t *authtag) { - - cryerror_t ret = CRY_NOERROR; - cgmcontext ctx; - - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (!(cryp->enabledPer & AES_PER)) { - cryp->enabledPer |= AES_PER; - pmcEnableAES(); - } - - ctx.params.encrypt = 0; - ctx.params.block_size = 16; - ctx.params.mode = AES_MR_OPMOD_GCM; - ctx.params.iv = iv; - - ctx.in =(uint8_t *) in; - ctx.out = out; - ctx.c_size = size; - ctx.aadsize = aadsize; - ctx.aad = (uint8_t *)aad; - ctx.authtag = authtag; - - - - ret = sama_gcm_lld_process(cryp, &ctx); - - return ret; - -} - - -/** - * @brief Encryption of a single block using (T)DES. - * @note The implementation of this function must guarantee that it can - * be called from any context. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out) { - - cryerror_t ret = CRY_NOERROR; - tdes_config_t params = { 0, 0 }; - - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (cryp->key0_size == 8) - { - params.algo = TDES_ALGO_SINGLE; - } - else if (cryp->key0_size == 16 || cryp->key0_size == 24) - { - params.algo = TDES_ALGO_TRIPLE; - } - else - return CRY_ERR_INV_KEY_SIZE; - - - if (!(cryp->enabledPer & TDES_PER)) { - cryp->enabledPer |= TDES_PER; - pmcEnableDES(); - } - - ret = sama_tdes_lld_polling(cryp, ¶ms, true, in, 8, out, NULL); - - return ret; -} - -/** - * @brief Decryption of a single block using (T)DES. - * @note The implementation of this function must guarantee that it can - * be called from any context. - * - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] in buffer containing the input cyphertext - * @param[out] out buffer for the output plaintext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out) { - - cryerror_t ret = CRY_NOERROR; - tdes_config_t params = { 0, 0 }; - - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (cryp->key0_size == 8) - { - params.algo = TDES_ALGO_SINGLE; - } - else if (cryp->key0_size == 16 || cryp->key0_size == 24) - { - params.algo = TDES_ALGO_TRIPLE; - } - else - return CRY_ERR_INV_KEY_SIZE; - - if (!(cryp->enabledPer & TDES_PER)) { - cryp->enabledPer |= TDES_PER; - pmcEnableDES(); - } - - ret = sama_tdes_lld_polling(cryp, ¶ms, false, in, 8, out, NULL); - - return ret; -} - -/** - * @brief Encryption operation using (T)DES-ECB. - * @note The function operates on data buffers whose length is a multiple - * of an DES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of 8 - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out) { - - cryerror_t ret = CRY_NOERROR; - tdes_config_t params = { 0, TDES_MODE_ECB }; - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (cryp->key0_size == 8) - { - params.algo = TDES_ALGO_SINGLE; - } - else if (cryp->key0_size == 16 || cryp->key0_size == 24) - { - params.algo = TDES_ALGO_TRIPLE; - } - else - return CRY_ERR_INV_KEY_SIZE; - - if (!(cryp->enabledPer & TDES_PER)) { - cryp->enabledPer |= TDES_PER; - pmcEnableDES(); - } - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_tdes_lld_polling(cryp, ¶ms, true, in, size, out, NULL); - else - ret = sama_tdes_lld_dma(cryp, ¶ms, true, in, size, out, NULL); - - return ret; -} - -/** - * @brief Decryption operation using (T)DES-ECB. - * @note The function operates on data buffers whose length is a multiple - * of an DES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of 8 - * @param[in] in buffer containing the input cyphertext - * @param[out] out buffer for the output plaintext - * @return T he operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out) { - - cryerror_t ret = CRY_NOERROR; - tdes_config_t params = { 0, TDES_MODE_ECB }; - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (cryp->key0_size == 8) - { - params.algo = TDES_ALGO_SINGLE; - } - else if (cryp->key0_size == 16 || cryp->key0_size == 24) - { - params.algo = TDES_ALGO_TRIPLE; - } - else - return CRY_ERR_INV_KEY_SIZE; - - if (!(cryp->enabledPer & TDES_PER)) { - cryp->enabledPer |= TDES_PER; - pmcEnableDES() - ; - } - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_tdes_lld_polling(cryp, ¶ms, false, in, size, out, NULL); - else - ret = sama_tdes_lld_dma(cryp, ¶ms, false, in, size, out, NULL); - - return ret; -} - -/** - * @brief Encryption operation using (T)DES-CBC. - * @note The function operates on data buffers whose length is a multiple - * of an DES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of 8 - * @param[in] in buffer containing the input plaintext - * @param[out] out buffer for the output cyphertext - * @param[in] iv 64 bits input vector - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - - cryerror_t ret = CRY_NOERROR; - tdes_config_t params = { 0, TDES_MODE_CBC }; - - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (cryp->key0_size == 8) - { - params.algo = TDES_ALGO_SINGLE; - } - else if (cryp->key0_size == 16 || cryp->key0_size == 24) - { - params.algo = TDES_ALGO_TRIPLE; - } - else - return CRY_ERR_INV_KEY_SIZE; - - if (!(cryp->enabledPer & TDES_PER)) { - cryp->enabledPer |= TDES_PER; - pmcEnableDES() - ; - } - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_tdes_lld_polling(cryp, ¶ms, true, in, size, out, iv); - else - ret = sama_tdes_lld_dma(cryp, ¶ms, true, in, size, out, iv); - return ret; -} - -/** - * @brief Decryption operation using (T)DES-CBC. - * @note The function operates on data buffers whose length is a multiple - * of an DES block, this means that padding must be done by the - * caller. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] key_id the key to be used for the operation, zero is - * the transient key, other values are keys stored - * in an unspecified way - * @param[in] size size of the plaintext buffer, this number must - * be a multiple of 8 - * @param[in] in buffer containing the input cyphertext - * @param[out] out buffer for the output plaintext - * @param[in] iv 64 bits input vector - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. - * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid - * or refers to an empty key slot. - * - * @notapi - */ -cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv) { - - cryerror_t ret = CRY_NOERROR; - tdes_config_t params = { 0, TDES_MODE_CBC }; - - if (key_id != 0) - return CRY_ERR_INV_KEY_ID; - - if (cryp->key0_size == 8) - { - params.algo = TDES_ALGO_SINGLE; - } - else if (cryp->key0_size == 16 || cryp->key0_size == 24) - { - params.algo = TDES_ALGO_TRIPLE; - } - else - return CRY_ERR_INV_KEY_SIZE; - - if (!(cryp->enabledPer & TDES_PER)) { - cryp->enabledPer |= TDES_PER; - pmcEnableDES() - ; - } - - if (cryp->config->transfer_mode == TRANSFER_POLLING) - ret = sama_tdes_lld_polling(cryp, ¶ms, false, in, size, out, iv); - else - ret = sama_tdes_lld_dma(cryp, ¶ms, false, in, size, out, iv); - - return ret; -} - - - -/** - * @brief Hash initialization using SHA1. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[out] sha1ctxp pointer to a SHA1 context to be initialized - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA1_init(CRYDriver *cryp, SHA1Context *sha1ctxp) { - - sha1ctxp->sha.algo = CRY_SHA_1; - - return sama_sha_lld_init(cryp, &sha1ctxp->sha); -} - -/** - * @brief Hash update using SHA1. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] sha1ctxp pointer to a SHA1 context - * @param[in] size size of input buffer - * @param[in] in buffer containing the input text - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA1_update(CRYDriver *cryp, SHA1Context *sha1ctxp, - size_t size, const uint8_t *in) { - - sha1ctxp->sha.in = in; - sha1ctxp->sha.indata_len = size; - - return sama_sha_lld_update(cryp, &sha1ctxp->sha); -} - -/** - * @brief Hash finalization using SHA1. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] sha1ctxp pointer to a SHA1 context - * @param[out] out 160 bits output buffer - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA1_final(CRYDriver *cryp, - SHA1Context *sha1ctxp, - uint8_t *out) -{ - sha1ctxp->sha.out = out; - return sama_sha_lld_final(cryp, &sha1ctxp->sha); -} - -/** - * @brief Hash initialization using SHA256. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[out] sha256ctxp pointer to a SHA256 context to be initialized - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp) { - - sha256ctxp->sha.algo = CRY_SHA_256; - - return sama_sha_lld_init(cryp, &sha256ctxp->sha); -} - -/** - * @brief Hash update using SHA256. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] sha256ctxp pointer to a SHA256 context - * @param[in] size size of input buffer - * @param[in] in buffer containing the input text - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp, - size_t size, const uint8_t *in) { - - sha256ctxp->sha.in = in; - sha256ctxp->sha.indata_len = size; - - return sama_sha_lld_update(cryp, &sha256ctxp->sha); -} - -/** - * @brief Hash finalization using SHA256. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] sha256ctxp pointer to a SHA256 context - * @param[out] out 256 bits output buffer - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA256_final(CRYDriver *cryp, SHA256Context *sha256ctxp, - uint8_t *out) { - - sha256ctxp->sha.out = out; - return sama_sha_lld_final(cryp, &sha256ctxp->sha); -} - -/** - * @brief Hash initialization using SHA512. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[out] sha512ctxp pointer to a SHA512 context to be initialized - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA512_init(CRYDriver *cryp, SHA512Context *sha512ctxp) { - sha512ctxp->sha.algo = CRY_SHA_512; - return sama_sha_lld_init(cryp, &sha512ctxp->sha); -} - -/** - * @brief Hash update using SHA512. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] sha512ctxp pointer to a SHA512 context - * @param[in] size size of input buffer - * @param[in] in buffer containing the input text - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA512_update(CRYDriver *cryp, SHA512Context *sha512ctxp, - size_t size, const uint8_t *in) { - - sha512ctxp->sha.in = in; - sha512ctxp->sha.indata_len = size; - - return sama_sha_lld_update(cryp, &sha512ctxp->sha); -} - -/** - * @brief Hash finalization using SHA512. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] sha512ctxp pointer to a SHA512 context - * @param[out] out 512 bits output buffer - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_SHA512_final(CRYDriver *cryp, SHA512Context *sha512ctxp, - uint8_t *out) { - - sha512ctxp->sha.out = out; - return sama_sha_lld_final(cryp, &sha512ctxp->sha); -} - -/** - * @brief True random numbers generator. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[out] out 128 bits output buffer - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @api - */ -cryerror_t cry_lld_TRNG(CRYDriver *cryp, uint8_t *out) { - - size_t i=0; - - osalMutexLock(&cryp->mutex); - - if (!(cryp->enabledPer & TRNG_PER)) { - cryp->enabledPer |= TRNG_PER; - pmcEnableTRNG(); - - //start trng - TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY_PASSWD; - } - while (i<4) { - while (!(TRNG->TRNG_ISR & TRNG_ISR_DATRDY)); - - ((uint32_t*) out)[i] = TRNG->TRNG_ODATA; - i++; - } - - osalMutexUnlock(&cryp->mutex); - - return (cryerror_t)CRY_NOERROR; -} - - -/** - * @brief Hash initialization using HMAC_SHA256. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[out] hmacsha256ctxp pointer to a HMAC_SHA256 context to be - * initialized - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_HMACSHA256_init(CRYDriver *cryp, - HMACSHA256Context *hmacsha256ctxp) { - - hmacsha256ctxp->kipad = 0; - - if (cryp->key0_size > HAL_CRY_MAX_KEY_SIZE) - return CRY_ERR_INV_KEY_SIZE; - - if (cryp->key0_size > 64) //this implementation doesn't hash the key - return CRY_ERR_INV_KEY_TYPE; - - return cry_lld_SHA256_init(cryp,&hmacsha256ctxp->shacontext); - -} - -/** - * @brief Hash update using HMAC. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] hmacsha256ctxp pointer to a HMAC_SHA256 context - * @param[in] size size of input buffer - * @param[in] in buffer containing the input text - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_HMACSHA256_update(CRYDriver *cryp, - HMACSHA256Context *hmacsha256ctxp, - size_t size, - const uint8_t *in) { - uint8_t i; - cryerror_t res; - CACHE_ALIGNED uint32_t buffer[16]; - - if (hmacsha256ctxp->kipad == 0) - { - memset(buffer,0,64); - memcpy(buffer,cryp->key0_buffer,cryp->key0_size); - - memset((uint8_t *)buffer + cryp->key0_size, 0, 64 - cryp->key0_size); - - for (i = 0; i < 16; ++i) { - buffer[i] ^= 0x36363636; - } - - - res = cry_lld_SHA256_update(cryp,&hmacsha256ctxp->shacontext,64,(const uint8_t *)buffer); - - hmacsha256ctxp->kipad = 1; - } - - if (res!= CRY_NOERROR) - return res; - - return cry_lld_SHA256_update(cryp,&hmacsha256ctxp->shacontext,size,in); - - -} - -/** - * @brief Hash finalization using HMAC. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] hmacsha256ctxp pointer to a HMAC_SHA256 context - * @param[out] out 256 bits output buffer - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ - -cryerror_t cry_lld_HMACSHA256_final(CRYDriver *cryp, - HMACSHA256Context *hmacsha256ctxp, - uint8_t *out) { - - uint8_t i; - cryerror_t res; - CACHE_ALIGNED uint32_t buffer[16]; //max block size for sha256 - CACHE_ALIGNED uint8_t digest[32]; - - //H( k1pad || m ) - - res = cry_lld_SHA256_final(cryp, &hmacsha256ctxp->shacontext,digest); - - if (res!= CRY_NOERROR) - return res; - - res = cry_lld_SHA256_init(cryp,&hmacsha256ctxp->shacontext); - - if (res!= CRY_NOERROR) - return res; - - memset(buffer,0,64); - memcpy(buffer,cryp->key0_buffer,cryp->key0_size); - - memset((uint8_t *)buffer + cryp->key0_size, 0, 64 - cryp->key0_size); - - for (i = 0; i < 16; ++i) { - buffer[i] ^= 0x5C5C5C5C; - } - - - // k+opad || H( k+ipad || m ) - res = cry_lld_SHA256_update(cryp,&hmacsha256ctxp->shacontext,64,(const uint8_t *)buffer); - - if (res!= CRY_NOERROR) - return res; - - res = cry_lld_SHA256_update(cryp,&hmacsha256ctxp->shacontext,32,digest); - - if (res!= CRY_NOERROR) - return res; - - hmacsha256ctxp->shacontext.sha.out = out; - - return cry_lld_SHA256_final(cryp, &hmacsha256ctxp->shacontext,out); -} - -/** - * @brief Hash initialization using HMAC_SHA512. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[out] hmacsha512ctxp pointer to a HMAC_SHA512 context to be - * initialized - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_HMACSHA512_init(CRYDriver *cryp, - HMACSHA512Context *hmacsha512ctxp) { - - hmacsha512ctxp->kipad = 0; - - if (cryp->key0_size > HAL_CRY_MAX_KEY_SIZE) - return CRY_ERR_INV_KEY_SIZE; - - if (cryp->key0_size > 128) //this implementation doesn't hash the key - return CRY_ERR_INV_KEY_TYPE; - - - return cry_lld_SHA512_init(cryp,&hmacsha512ctxp->shacontext); -} - -/** - * @brief Hash update using HMAC. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] hmacsha512ctxp pointer to a HMAC_SHA512 context - * @param[in] size size of input buffer - * @param[in] in buffer containing the input text - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_HMACSHA512_update(CRYDriver *cryp, - HMACSHA512Context *hmacsha512ctxp, - size_t size, - const uint8_t *in) { - - cryerror_t res; - uint8_t i; -CACHE_ALIGNED uint32_t buffer[32]; - - if (hmacsha512ctxp->kipad == 0) - { - memset(buffer,0,128); - memcpy(buffer,cryp->key0_buffer,cryp->key0_size); - - - memset((uint8_t *)buffer + cryp->key0_size, 0, 128 - cryp->key0_size); - - for (i = 0; i < 32; ++i) { - buffer[i] ^= 0x36363636; - } - - - res = cry_lld_SHA512_update(cryp,&hmacsha512ctxp->shacontext,128,(const uint8_t *)buffer); - - if (res!= CRY_NOERROR) - return res; - - hmacsha512ctxp->kipad = 1; - } - - return cry_lld_SHA512_update(cryp,&hmacsha512ctxp->shacontext,size,in); -} - -/** - * @brief Hash finalization using HMAC. - * @note Use of this algorithm is not recommended because proven weak. - * - * @param[in] cryp pointer to the @p CRYDriver object - * @param[in] hmacsha512ctxp pointer to a HMAC_SHA512 context - * @param[out] out 512 bits output buffer - * @return The operation status. - * @retval CRY_NOERROR if the operation succeeded. - * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this - * device instance. - * - * @notapi - */ -cryerror_t cry_lld_HMACSHA512_final(CRYDriver *cryp, - HMACSHA512Context *hmacsha512ctxp, - uint8_t *out) { - - uint8_t i; - cryerror_t res; - CACHE_ALIGNED uint32_t buffer[32]; //max block size for sha256 - CACHE_ALIGNED uint8_t digest[64]; - - //H( k1pad || m ) - - res = cry_lld_SHA512_final(cryp, &hmacsha512ctxp->shacontext,digest); - - if (res!= CRY_NOERROR) - return res; - - res = cry_lld_SHA512_init(cryp,&hmacsha512ctxp->shacontext); - - if (res!= CRY_NOERROR) - return res; - - - memset(buffer,0,128); - memcpy(buffer,cryp->key0_buffer,cryp->key0_size); - - memset((uint8_t *)buffer + cryp->key0_size, 0, 128 - cryp->key0_size); - - for (i = 0; i < 32; ++i) { - buffer[i] ^= 0x5C5C5C5C; - } - - - // k+opad || H( k+ipad || m ) - res = cry_lld_SHA512_update(cryp,&hmacsha512ctxp->shacontext,128,(const uint8_t *)buffer); - - if (res!= CRY_NOERROR) - return res; - - res = cry_lld_SHA512_update(cryp,&hmacsha512ctxp->shacontext,64,digest); - - if (res!= CRY_NOERROR) - return res; - - hmacsha512ctxp->shacontext.sha.out = out; - - return cry_lld_SHA512_final(cryp, &hmacsha512ctxp->shacontext,out); -} - - -#endif /* HAL_USE_CRY */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h deleted file mode 100644 index 5e5ce362d..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h +++ /dev/null @@ -1,448 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_crypto_lld.h - * @brief PLATFORM cryptographic subsystem low level driver header. - * - * @addtogroup CRYPTO - * @{ - */ - -#ifndef HAL_CRYPTO_LLD_H -#define HAL_CRYPTO_LLD_H - -#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Driver capability switches - * @{ - */ -#define CRY_LLD_SUPPORTS_AES TRUE -#define CRY_LLD_SUPPORTS_AES_ECB TRUE -#define CRY_LLD_SUPPORTS_AES_CBC TRUE -#define CRY_LLD_SUPPORTS_AES_CFB TRUE -#define CRY_LLD_SUPPORTS_AES_CTR TRUE -#define CRY_LLD_SUPPORTS_AES_GCM TRUE -#define CRY_LLD_SUPPORTS_DES TRUE -#define CRY_LLD_SUPPORTS_DES_ECB TRUE -#define CRY_LLD_SUPPORTS_DES_CBC TRUE -#define CRY_LLD_SUPPORTS_SHA1 TRUE -#define CRY_LLD_SUPPORTS_SHA256 TRUE -#define CRY_LLD_SUPPORTS_SHA512 TRUE -#define CRY_LLD_SUPPORTS_HMAC_SHA256 TRUE -#define CRY_LLD_SUPPORTS_HMAC_SHA512 TRUE -#define CRY_LLD_SUPPORTS_TRNG TRUE -/** @{ */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name PLATFORM configuration options - * @{ - */ -/** - * @brief CRY1 driver enable switch. - * @details If set to @p TRUE the support for CRY1 is included. - * @note The default is @p FALSE. - */ -#if !defined(PLATFORM_CRY_USE_CRY1) || defined(__DOXYGEN__) -#define PLATFORM_CRY_USE_CRY1 FALSE -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -typedef struct -{ - uint32_t encrypt; - uint32_t block_size; - uint32_t mode; - const uint8_t *iv; -}aesparams; - -typedef struct -{ - aesparams params; - - - size_t aadsize; - size_t c_size; - uint8_t *in; - uint8_t *out; - - uint8_t * aad; - uint8_t *authtag; - -}cgmcontext; - -typedef enum { - TRANSFER_DMA = 0, - TRANSFER_POLLING, -}crytransfermode_t; - -typedef enum { - AES_CFBS_128 = 0, - AES_CFBS_64, - AES_CFBS_32, - AES_CFBS_16, - AES_CFBS_8 -}aesciphersize_t; - - -typedef enum { - CRY_SHA_1, - CRY_SHA_224, - CRY_SHA_256, - CRY_SHA_384, - CRY_SHA_512, - - CRY_HMACSHA_1, - CRY_HMACSHA_224, - CRY_HMACSHA_256, - CRY_HMACSHA_384, - CRY_HMACSHA_512, - -}shadalgo_t; - -typedef struct -{ - shadalgo_t algo; -}shaparams_t; - -/** - * @brief CRY key identifier type. - */ -typedef uint32_t crykey_t; - -/** - * @brief Type of a structure representing an CRY driver. - */ -typedef struct CRYDriver CRYDriver; - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ - - -typedef enum { - TDES_ALGO_SINGLE = 0, - TDES_ALGO_TRIPLE, - TDES_ALGO_XTEA -}tdes_algo_t; - -struct sha_data { - uint32_t remaining; - uint32_t processed; - uint32_t block_size; - uint32_t output_size; - uint32_t sha_buffer_size; - const uint8_t *in; - uint8_t *out; - size_t indata_len; - uint8_t *sha_buffer; - - shadalgo_t algo; -}; - -typedef struct { - - crytransfermode_t transfer_mode; - uint32_t cfbs; -} CRYConfig; - -#define KEY0_BUFFER_SIZE_W HAL_CRY_MAX_KEY_SIZE/4 - - -#define CRY_DRIVER_EXT_FIELDS thread_reference_t thread; \ - sama_dma_channel_t *dmarx; \ - sama_dma_channel_t *dmatx; \ - uint32_t rxdmamode; \ - uint32_t txdmamode; \ - uint8_t dmawith; \ - uint8_t dmachunksize; \ - uint8_t enabledPer; \ - mutex_t mutex; \ - uint32_t key0_buffer[KEY0_BUFFER_SIZE_W]; - -/** - * @brief Structure representing an CRY driver. - */ -struct CRYDriver { - /** - * @brief Driver state. - */ - crystate_t state; - /** - * @brief Current configuration data. - */ - const CRYConfig *config; - /** - * @brief Algorithm type of transient key. - */ - cryalgorithm_t key0_type; - /** - * @brief Size of transient key. - */ - size_t key0_size; - /** - * @brief Pointer to the in buffer location. - */ - const uint8_t *in; - /** - * @brief Pointer to the out buffer location. - */ - uint8_t *out; - /** - * @brief Number of bytes. - */ - size_t len; -#if (HAL_CRY_USE_FALLBACK == TRUE) || defined(__DOXYGEN__) - /** - * @brief Key buffer for the fall-back implementation. - */ - uint8_t key0_buffer[HAL_CRY_MAX_KEY_SIZE]; -#endif -#if defined(CRY_DRIVER_EXT_FIELDS) - CRY_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ -}; - -#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__) -/** - * @brief Type of a SHA1 context. - */ -typedef struct { - struct sha_data sha; -} SHA1Context; -#endif - -#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__) -/** - * @brief Type of a SHA256 context. - */ -typedef struct { - struct sha_data sha; -} SHA256Context; -#endif - -#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__) -/** - * @brief Type of a SHA512 context. - */ -typedef struct { - struct sha_data sha; -} SHA512Context; -#endif -#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__) -/** - * @brief Type of a HMAC_SHA256 context. - */ -typedef struct { - SHA256Context shacontext; - uint8_t kipad; -} HMACSHA256Context; -#endif - -#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__) -/** - * @brief Type of a HMAC_SHA512 context. - */ -typedef struct { - SHA512Context shacontext; - uint8_t kipad; -} HMACSHA512Context; -#endif - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if (PLATFORM_CRY_USE_CRY1 == TRUE) && !defined(__DOXYGEN__) -extern CRYDriver CRYD1; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void cry_lld_init(void); - void cry_lld_start(CRYDriver *cryp); - void cry_lld_stop(CRYDriver *cryp); - cryerror_t cry_lld_loadkey(CRYDriver *cryp, - cryalgorithm_t algorithm, - size_t size, - const uint8_t *keyp); - cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv, - size_t aadsize, - const uint8_t *aad, - uint8_t *authtag); - cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv, - size_t aadsize, - const uint8_t *aad, - uint8_t *authtag); - cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp, - crykey_t key_id, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out); - cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp, - crykey_t key_id, - size_t size, - const uint8_t *in, - uint8_t *out, - const uint8_t *iv); - cryerror_t cry_lld_SHA1_init(CRYDriver *cryp, SHA1Context *sha1ctxp); - cryerror_t cry_lld_SHA1_update(CRYDriver *cryp, SHA1Context *sha1ctxp, - size_t size, const uint8_t *in); - cryerror_t cry_lld_SHA1_final(CRYDriver *cryp, SHA1Context *sha1ctxp, - uint8_t *out); - cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp); - cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp, - size_t size, const uint8_t *in); - cryerror_t cry_lld_SHA256_final(CRYDriver *cryp, SHA256Context *sha256ctxp, - uint8_t *out); - cryerror_t cry_lld_SHA512_init(CRYDriver *cryp, SHA512Context *sha512ctxp); - cryerror_t cry_lld_SHA512_update(CRYDriver *cryp, SHA512Context *sha512ctxp, - size_t size, const uint8_t *in); - cryerror_t cry_lld_SHA512_final(CRYDriver *cryp, SHA512Context *sha512ctxp, - uint8_t *out); - cryerror_t cry_lld_HMACSHA256_init(CRYDriver *cryp, - HMACSHA256Context *hmacsha256ctxp); - cryerror_t cry_lld_HMACSHA256_update(CRYDriver *cryp, - HMACSHA256Context *hmacsha256ctxp, - size_t size, const uint8_t *in); - cryerror_t cry_lld_HMACSHA256_final(CRYDriver *cryp, - HMACSHA256Context *hmacsha256ctxp, - uint8_t *out); - cryerror_t cry_lld_HMACSHA512_init(CRYDriver *cryp, - HMACSHA512Context *hmacsha512ctxp); - cryerror_t cry_lld_HMACSHA512_update(CRYDriver *cryp, - HMACSHA512Context *hmacsha512ctxp, - size_t size, const uint8_t *in); - cryerror_t cry_lld_HMACSHA512_final(CRYDriver *cryp, - HMACSHA512Context *hmacsha512ctxp, - uint8_t *out); - cryerror_t cry_lld_TRNG(CRYDriver *cryp, uint8_t *out); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_CRY == TRUE */ - -#endif /* HAL_CRYPTO_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_lld.c deleted file mode 100644 index 623d20b7a..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_lld.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 hal_lld.c - * @brief PLATFORM HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define SAMA_MOR_ONE (1 << 5) -#define SAMA_MOR_MOSCXTST CKGR_MOR_MOSCXTST(0xFF) - -#define SAMA_PLLA_ONE (1 << 29) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - -#if (SAMA_HAL_IS_SECURE == TRUE) /* The Matrix is PAS and PMC is always configured secure */ - /* Disabling PMC write protection. */ - pmcDisableWP(); - - PIT->PIT_MR &= ~(PIT_MR_PITEN | PIT_MR_PITIEN); - - /* Configures peripherals as not-secure */ - MATRIX0->MATRIX_SPSELR[0] = 0xFFFFFFFF; - MATRIX0->MATRIX_SPSELR[1] = 0xFFFFFFFF; - MATRIX0->MATRIX_SPSELR[2] = 0xFFFFFFFF; - MATRIX1->MATRIX_SPSELR[0] = 0xFFFFFFFF; - MATRIX1->MATRIX_SPSELR[1] = 0xFFFFFFFF; - MATRIX1->MATRIX_SPSELR[2] = 0xFFFFFFFF; - - /* Configures PMC and RTC as secure */ - //mtxConfigPeriphSecurity(MATRIX1, ID_SYSC, SECURE_PER); - mtxConfigPeriphSecurity(MATRIX0, ID_PMC, SECURE_PER); - mtxConfigPeriphSecurity(MATRIX1, ID_SFC, SECURE_PER); - mtxConfigPeriphSecurity(MATRIX1, ID_SFR, SECURE_PER); - - /* It isn't necessary to make L2CC secure. L2C-310 cache - * controller is secure mode aware.*/ - /*mtxConfigPeriphSecurity(MATRIX0, ID_L2CC, SECURE_PER);*/ - - mtxConfigPeriphSecurity(MATRIX1, ID_SFRBU, SECURE_PER); - /*mtxConfigPeriphSecurity(MATRIX1, ID_CHIPID, SECURE_PER);*/ - - /* Enabling matrix clock */ - pmcEnableH32MX(); - pmcEnableH64MX(); - /* Enabling write protection. */ - pmcEnableWP(); -#endif - - /* Advanced interrupt controller init */ - aicInit(); - -#if defined(SAMA_DMA_REQUIRED) - dmaInit(); -#endif - -} - -/** - * @brief SAMA clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void sama_clock_init(void) { -#if (!SAMA_NO_INIT && SAMA_HAL_IS_SECURE == TRUE) - uint32_t mor, pllar, mckr, mainf; - /* Disabling PMC write protection. */ - pmcDisableWP(); - - /* - * Enforcing the reset default configuration of clock tree. - */ - /* Setting Slow Clock source to OSCRC. */ - SCKC->SCKC_CR = 0U; - - /* Enabling MOSCRC. */ - PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN); - while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)) - ; /* Waits until MOSCRC is stable.*/ - - /* Switching Main Oscillator Source to MOSRC. */ - mor = PMC->CKGR_MOR | CKGR_MOR_KEY_PASSWD; - mor &= ~CKGR_MOR_MOSCSEL; - mor |= SAMA_MOSC_MOSCRC; - PMC->CKGR_MOR = mor; - - while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) - ; /* Waits until MOSCSEL has changed.*/ - - /* Switching Master Clock source to Main Clock. */ - mckr = PMC->PMC_MCKR; - mckr &= ~PMC_MCKR_CSS_Msk; - mckr |= PMC_MCKR_CSS_MAIN_CLK; - PMC->PMC_MCKR = mckr; - - while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) - ; /* Waits until Master Clock is stable.*/ - - /* Counter Clock Source to MOSCRC. */ - PMC->CKGR_MCFR &= ~CKGR_MCFR_CCSS; - - - /* - * Main oscillator configuration block. - */ - /* Setting Slow clock source. */ - SCKC->SCKC_CR = SAMA_OSC_SEL; - while ((SAMA_OSC_SEL && !(PMC->PMC_SR & PMC_SR_OSCSELS)) || - (!SAMA_OSC_SEL && (PMC->PMC_SR & PMC_SR_OSCSELS))) - ; /* Waits until MOSCxxS switch is done.*/ - mor = PMC->CKGR_MOR | CKGR_MOR_KEY_PASSWD; -#if SAMA_MOSCXT_ENABLED - mor |= CKGR_MOR_MOSCXTEN; - PMC->CKGR_MOR = mor; - while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) - ; /* Waits until MOSCXT is stable.*/ - /* Counter Clock Source to MOSCXT. */ - PMC->CKGR_MCFR |= CKGR_MCFR_CCSS; -#else - mor &= ~CKGR_MOR_MOSCXTEN; - PMC->CKGR_MOR = mor; -#endif - - PMC->CKGR_MCFR |= CKGR_MCFR_RCMEAS; - while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY)) - ; - mainf = CKGR_MCFR_MAINF(PMC->CKGR_MCFR); - /* - * @TODO: add mainf check and eventual clock source fallback. This mechanism - * should be activable through a switch. - */ - (void)mainf; - - /* Switching Main Clock source. */ - mor &= ~CKGR_MOR_MOSCSEL; - mor |= SAMA_MOSC_SEL; - PMC->CKGR_MOR = mor; - - /* Eventually disabling MOSCRC. */ -#if !SAMA_MOSCRC_ENABLED - PMC->CKGR_MOR &= ~ CKGR_MOR_MOSCRCEN; -#endif - -/* - * PLLA configuration block. - */ - pllar = SAMA_PLLA_ONE | CKGR_PLLAR_PLLACOUNT(0x3F); -#if SAMA_ACTIVATE_PLLA - pllar |= CKGR_PLLAR_DIVA_BYPASS | SAMA_PLLA_MUL; -#endif - PMC->CKGR_PLLAR = pllar; /* Writing PLLA register. */ - -#if SAMA_ACTIVATE_PLLA - while (!(PMC->PMC_SR & PMC_SR_LOCKA)) - ; /* Waits until PLLA is locked. */ -#endif - -/* - * Master clock configuration block. - */ - mckr = PMC->PMC_MCKR; - mckr &= ~PMC_MCKR_CSS_Msk; - mckr |= SAMA_MCK_SEL; - PMC->PMC_MCKR = mckr; - while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) - ; /* Waits until MCK is stable. */ - - mckr &= ~(PMC_MCKR_PRES_Msk | PMC_MCKR_MDIV_Msk | PMC_MCKR_H32MXDIV); - - /* Note that prescaler and divider must be changed with separate accesses.*/ - mckr |= SAMA_MCK_PRES; - mckr |= SAMA_MCK_MDIV; - mckr |= SAMA_H64MX_H32MX_DIV; -#if SAMA_PLLADIV2_EN - mckr |= PMC_MCKR_PLLADIV2; -#else - mckr &= ~PMC_MCKR_PLLADIV2; -#endif - PMC->PMC_MCKR = mckr; - while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) - ; /* Waits until MCK is stable. */ - - /* Enabling write protection. */ - pmcEnableWP(); - -#endif /* !SAMA_NO_INIT */ -} -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_lld.h deleted file mode 100644 index 5c5669ecd..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_lld.h +++ /dev/null @@ -1,545 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/hal_lld.h - * @brief SAMA5D2x HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - SAMA_MOSCXTCLK. - * - SAMA_OSCXTCLK - * . - * One of the following macros must also be defined: - * - SAMA5D21, SAMA5D22, SAMA5D23, SAMA5D24, SAMA5D25, SAMA5D26, - * SAMA5D27, SAMA5D28. - * - * @addtogroup HAL - * @{ - */ - -#ifndef _HAL_LLD_H_ -#define _HAL_LLD_H_ - -#include "sama_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification macros - * @{ - */ -#if defined(SAMA5D21) || defined(__DOXYGEN__) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16-bit DDR, BGA196" - -#elif defined(SAMA5D22) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16-bit DDR, CAN, BGA196" - -#elif defined(SAMA5D23) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16-bit DDR, CAN, Enhanced Security, BGA196" - -#elif defined(SAMA5D24) -#define PLATFORM_NAME "A500Mhz processor with TrustZone, 16/32-bit DDR, USB HSIC, BGA256" - -#elif defined(SAMA5D25) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, BGA289" - -#elif defined(SAMA5D26) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, CAN, BGA289" - -#elif defined(SAMA5D27) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, CAN, Enhanced Security, BGA289" - -#elif defined(SAMA5D28) -#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, CAN, Enhanced Security, BGA289, 'internal DDR" - -#else -#error "SAMA5D2x device unsupported or not specified" -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum processor clock frequency. - */ -#define SAMA_PCK_MAX 504000000 - -/** - * @brief Minimum processor clock frequency. - */ -#define SAMA_PCK_MIN 250000000 - -/** - * @brief Maximum master clock frequency. - */ -#define SAMA_MCK_MAX 168000000 - -/** - * @brief Minimum master clock frequency. - */ -#define SAMA_MCK_MIN 125000000 - -/** - * @brief Maximum Main Crystal Oscillator clock frequency. - */ -#define SAMA_MOSCXTCLK_MAX 24000000 - -/** - * @brief Minimum Main Crystal Oscillator clock frequency. - */ -#define SAMA_MOSCXTCLK_MIN 8000000 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define SAMA_PLLIN_MAX 24000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define SAMA_PLLIN_MIN 800000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define SAMA_PLLOUT_MAX 1200000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define SAMA_PLLOUT_MIN 600000000 -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define SAMA_MOSCRCCLK 12000000 /**< RC Main oscillator clock. */ -#define SAMA_OSCRCCLK 32000 /**< RC Slow oscillator clock. */ -/** @} */ - -/** - * @name SCK_CR register bits definitions - * @{ - */ -#define SAMA_OSC_OSCRC (0 << 3) /**< Slow Clock source MOSCRC. */ -#define SAMA_OSC_OSCXT (1 << 3) /**< Slow Clock source MOSCXT. */ -/** @} */ - -/** - * @name PCM_MOR register bits definitions - * @{ - */ -#define SAMA_MOSC_MOSCRC (0 << 24) /**< Main Clock source MOSCRC. */ -#define SAMA_MOSC_MOSCXT (1 << 24) /**< Main Clock source MOSCXT. */ -/** @} */ - -/** - * @name PCM_MCR register bits definitions - * @{ - */ -#define SAMA_MCK_SLOW_CLK (0 << 0) /**< MCK source is Slow Clock. */ -#define SAMA_MCK_MAIN_CLK (1 << 0) /**< MCK source is Main Clock. */ -#define SAMA_MCK_PLLA_CLK (2 << 0) /**< MCK source is PLLA Clock. */ -#define SAMA_MCK_UPLL_CLK (3 << 0) /**< MCK source is UPLL Clock. */ - -#define SAMA_MCK_PRE_DIV1 (0 << 4) /**< MCK not prescaled. */ -#define SAMA_MCK_PRE_DIV2 (1 << 4) /**< MCK prescaled by 2. */ -#define SAMA_MCK_PRE_DIV4 (2 << 4) /**< MCK prescaled by 4. */ -#define SAMA_MCK_PRE_DIV8 (3 << 4) /**< MCK prescaled by 8. */ -#define SAMA_MCK_PRE_DIV16 (4 << 4) /**< MCK prescaled by 16. */ -#define SAMA_MCK_PRE_DIV32 (5 << 4) /**< MCK prescaled by 32. */ -#define SAMA_MCK_PRE_DIV64 (6 << 4) /**< MCK prescaled by 64. */ - -#define SAMA_MCK_MDIV_DIV1 (0 << 8) /**< MCK is not divided. */ -#define SAMA_MCK_MDIV_DIV2 (1 << 8) /**< MCK is divided by 2. */ -#define SAMA_MCK_MDIV_DIV3 (3 << 8) /**< MCK is divided by 3. */ -#define SAMA_MCK_MDIV_DIV4 (2 << 8) /**< MCK is divided by 4. */ - -#define SAMA_MCK_PLLADIV2 (1 << 12) /**< PLLA is divided by 2. */ - -/** - * @name PCM_PCR register bits definitions - * @{ - */ -#define SAMA_GCLK_SLOW_CLK (0x0u << 8) /**< GCLK Slow clock is selected */ -#define SAMA_GCLK_MAIN_CLK (0x1u << 8) /**< GCLK GMain clock is selected */ -#define SAMA_GCLK_PLLA_CLK (0x2u << 8) /**< GCLK PLLACK is selected */ -#define SAMA_GCLKUPLL_CLK (0x3u << 8) /**< GCLK UPLL Clock is selected */ -#define SAMA_GCLK_MCK_CLK (0x4u << 8) /**< GCLK Master Clock is selected */ -#define SAMA_GCLK_AUDIO_CLK (0x5u << 8) /**< GCLK Audio PLL clock is selected */ - -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Defines if the code is running in the secure side of the ARM Trust - * Zone. It must be @p TRUE whenever the code is compiled for the - * secure side. - */ -#if !defined(SAMA_HAL_IS_SECURE) || defined(__DOXYGEN__) -#define SAMA_HAL_IS_SECURE TRUE -#endif - -/** - * @brief Disables the PMC initialization in the HAL. - */ -#if !defined(SAMA_NO_INIT) || defined(__DOXYGEN__) -#define SAMA_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the MOSCRC clock source. - */ -#if !defined(SAMA_MOSCRC_ENABLED) || defined(__DOXYGEN__) -#define SAMA_MOSCRC_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the MOSCXT clock source. - */ -#if !defined(SAMA_MOSCXT_ENABLED) || defined(__DOXYGEN__) -#define SAMA_MOSCXT_ENABLED FALSE -#endif - -/** - * @brief Main clock source selection. - */ -#if !defined(SAMA_MOSC_SEL) || defined(__DOXYGEN__) -#define SAMA_MOSC_SEL SAMA_MOSC_MOSCRC -#endif - -/** - * @brief Slow clock source selection. - */ -#if !defined(SAMA_OSC_SEL) || defined(__DOXYGEN__) -#define SAMA_OSC_SEL SAMA_OSC_OSCRC -#endif - -/** - * @brief Master clock source selection. - */ -#if !defined(SAMA_MCK_SEL) || defined(__DOXYGEN__) -#define SAMA_MCK_SEL SAMA_MCK_PLLA_CLK -#endif - -/** - * @brief Master clock prescaler. - */ -#if !defined(SAMA_MCK_PRES_VALUE) || defined(__DOXYGEN__) -#define SAMA_MCK_PRES_VALUE 1 -#endif - -/** - * @brief Master clock divider. - */ -#if !defined(SAMA_MCK_MDIV_VALUE) || defined(__DOXYGEN__) -#define SAMA_MCK_MDIV_VALUE 3 -#endif - -/** - * @brief PLLA clock multiplier. - */ -#if !defined(SAMA_PLLA_MUL_VALUE) || defined(__DOXYGEN__) -#define SAMA_PLLA_MUL_VALUE 83 -#endif - -/** - * @brief PLLADIV2 clock divider. - */ -#if !defined(SAMA_PLLADIV2_EN) || defined(__DOXYGEN__) -#define SAMA_PLLADIV2_EN TRUE -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(SAMA5D2x_MCUCONF) -#error "Using a wrong mcuconf.h file, SAMA5D2x_MCUCONF not defined" -#endif - -/** - * @brief Slow clock value. - */ -/* Main oscillator is fed by internal RC. */ -#if (SAMA_OSC_SEL == SAMA_OSC_OSCRC) || defined(__DOXYGEN__) -#define SAMA_SLOW_CLK SAMA_OSCRCCLK -#elif (SAMA_OSC_SEL == SAMA_OSC_OSCXT) -#define SAMA_SLOW_CLK SAMA_OSCXTCLK -#else -#error "Wrong SAMA_OSC_SEL value." -#endif - -/** - * @brief MAIN clock value. - */ -/* Main oscillator is fed by internal RC. */ -#if (SAMA_MOSC_SEL == SAMA_MOSC_MOSCRC) || defined(__DOXYGEN__) -#if !SAMA_MOSCRC_ENABLED -#error "Internal RC oscillator disabled (required by SAMA_MOSC_SEL)." -#endif -#define SAMA_MAIN_CLK SAMA_MOSCRCCLK - -/* Main oscillator is fed by external XTAL. */ -#elif (SAMA_MOSC_SEL == SAMA_MOSC_MOSCXT) -#if !SAMA_MOSCXT_ENABLED -#error "External crystal oscillator disabled (required by SAMA_MOSC_SEL)." -#endif -#define SAMA_MAIN_CLK SAMA_MOSCXTCLK -/* Checks on external crystal range. */ -#if (SAMA_MOSCXTCLK > SAMA_MOSCXTCLK_MAX) || \ - (SAMA_MOSCXTCLK < SAMA_MOSCXTCLK_MIN) -#error "External crystal oscillator out of range." -#endif - -/* Unallowed condition. */ -#else -#error "Wrong SAMA_MOSC_SEL value." -#endif /* SAMA_MOSCXTCLK */ - -#if (SAMA_MCK_SEL == SAMA_MCK_PLLA_CLK) || defined(__DOXYGEN__) -#define SAMA_ACTIVATE_PLLA TRUE -#else -#define SAMA_ACTIVATE_PLLA FALSE -#endif - -/** - * @brief PLLAMUL field. - */ -#if ((SAMA_PLLA_MUL_VALUE >= 1) && (SAMA_PLLA_MUL_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define SAMA_PLLA_MUL ((SAMA_PLLA_MUL_VALUE - 1) << 18) -#else -#error "invalid SAMA_PLLA_MUL_VALUE value specified" -#endif - -/** - * @brief PLLA input clock frequency. - * @todo Consider to add DIVA to this. On SAMA5D27 DIVA is a nonsense since - * it could be only 1 or 0 whereas 0 means PLLA disabled. This could - * be useful for other chip belonging to this family - */ -#define SAMA_PLLACLKIN SAMA_MAIN_CLK - -/* PLLA input frequency range check.*/ -#if (SAMA_PLLACLKIN < SAMA_PLLIN_MIN) || (SAMA_PLLACLKIN > SAMA_PLLIN_MAX) -#error "SAMA_PLLACLKIN out of range" -#endif - -/** - * @brief PLLA output clock frequency. - */ -#define SAMA_PLLACLKOUT (SAMA_MAIN_CLK * SAMA_PLLA_MUL_VALUE) - -/* PLLA output frequency range check.*/ -#if (SAMA_PLLACLKOUT < SAMA_PLLOUT_MIN) || (SAMA_PLLACLKOUT > SAMA_PLLOUT_MAX) -#error "SAMA_PLLACLKOUT out of range" -#endif - -/** - * @brief PLLADIV2 divider value. - */ -#if SAMA_PLLADIV2_EN || defined(__DOXYGEN__) -#define SAMA_PLLADIV2 SAMA_MCK_PLLADIV2 -#else -#define SAMA_PLLADIV 0 -#endif - -/** - * @brief Master Clock prescaler. - */ -#if (SAMA_MCK_PRES_VALUE == 1) || defined(__DOXYGEN__) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV1 -#elif (SAMA_MCK_PRES_VALUE == 2) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV2 -#elif (SAMA_MCK_PRES_VALUE == 4) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV4 -#elif (SAMA_MCK_PRES_VALUE == 8) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV8 -#elif (SAMA_MCK_PRES_VALUE == 16) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV16 -#elif (SAMA_MCK_PRES_VALUE == 32) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV32 -#elif (SAMA_MCK_PRES_VALUE == 64) -#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV64 -#else -#error "Wrong SAMA_MCK_PRES_VALUE." -#endif - -/** - * @brief Master Clock divider. - */ -#if (SAMA_MCK_MDIV_VALUE == 1) || defined(__DOXYGEN__) -#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV1 -#elif (SAMA_MCK_MDIV_VALUE == 2) -#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV2 -#elif (SAMA_MCK_MDIV_VALUE == 3) -#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV3 -#elif (SAMA_MCK_MDIV_VALUE == 4) -#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV4 -#else -#error "Wrong SAMA_MCK_MDIV_VALUE." -#endif - -/* Check on MDIV and PLLADIV2 value. */ -#if (SAMA_MCK_MDIV == SAMA_MCK_MDIV_DIV3) && !SAMA_PLLADIV2_EN -#error "PLLADIV2 must be always enabled when Main Clock Divider is 3" -#endif - -/** - * @brief Processor Clock frequency. - */ -#if (SAMA_MCK_SEL == SAMA_MCK_SLOW_CLK) || defined(__DOXYGEN__) -#define SAMA_PCK (SAMA_SLOW_CLK / SAMA_MCK_PRES_VALUE) -#elif (SAMA_MCK_SEL == SAMA_MCK_MAIN_CLK) -#define SAMA_PCK (SAMA_MAIN_CLK / SAMA_MCK_PRES_VALUE) -#elif (SAMA_MCK_SEL == SAMA_MCK_PLLA_CLK) -#if SAMA_PLLADIV2_EN -#define SAMA_PCK (SAMA_PLLACLKOUT / SAMA_MCK_PRES_VALUE / 2) -#else -#define SAMA_PCK (SAMA_PLLACLKOUT / SAMA_MCK_PRES_VALUE) -#endif -#elif (SAMA_MCK_SEL == SAMA_MCK_UPLL_CLK) -#error "UPLL still unsupported" -#else -#error "Wrong SAMA_MCK_SEL." -#endif - -/** - * @brief Master Clock frequency. - */ -#define SAMA_MCK (SAMA_PCK / SAMA_MCK_MDIV_VALUE) - -/* Checks on Processor Clock crystal range. */ -#if (SAMA_PCK > SAMA_PCK_MAX) || (SAMA_PCK < SAMA_PCK_MIN) -#error "Processor clock frequency out of range." -#endif - -/* Checks on Master Clock crystal range. */ -#if (SAMA_MCK > SAMA_MCK_MAX) || (SAMA_MCK < SAMA_MCK_MIN) -#error "Master clock frequency out of range." -#define VALUE(x) #x -#define VAR_NAME_VALUE(var) #var "=" VALUE(var) -#pragma message(VAR_NAME_VALUE(SAMA_MCK)) - -#endif - -/** - * @brief Matrix H64H32 clock ratio. - */ -#if ((SAMA_H64MX_H32MX_RATIO == 2) || defined(__DOXYGEN__)) -#define SAMA_H64MX_H32MX_DIV PMC_MCKR_H32MXDIV_H32MXDIV2 -#elif (SAMA_H64MX_H32MX_RATIO == 1) -#define SAMA_H64MX_H32MX_DIV PMC_MCKR_H32MXDIV_H32MXDIV1 -#if (SAMA_MCK > 83000000) -#error "Invalid H32MXCLK. MCK > 83MHz wants SAMA_H64MX_H32MX_RATIO == 2" -#endif -#else -#error "H64MX H32MX clock ratio out of range." -#endif - -/** - * @brief UARTx clock. - * TODO: Work only with PERIPH CLOCK - */ -#define SAMA_UART0CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_UART1CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_UART2CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_UART3CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_UART4CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) - -/** - * @brief FLEXCOMx clock. - * TODO: Work only with PERIPH CLOCK - */ -#define SAMA_FLEXCOM0CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_FLEXCOM1CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_FLEXCOM2CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_FLEXCOM3CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_FLEXCOM4CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) - -/** - * @brief TCx clock. - * TODO: Work only with PERIPH CLOCK - */ -#define SAMA_TC0CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) -#define SAMA_TC1CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) - -/** - * @brief GMAC0 clock. - * TODO: Work only with PERIPH CLOCK - */ -#define SAMA_GMAC0CLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) - -/** - * @brief TWIHSx clock. - * TODO: Work only with PERIPH CLOCK - */ -#define SAMA_TWIHSxCLK (SAMA_MCK / SAMA_H64MX_H32MX_RATIO) - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "sama_pmc.h" -#include "sama_aic.h" -#include "sama_matrix.h" -#include "sama_xdmac.h" -#include "sama_cache.h" -#include "sama_tc_lld.h" -#include "sama_lcdc.h" -#include "sama_secumod.h" -#include "sama_onewire.h" -#include "sama_classd.h" -#include "sama_rstc.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void sama_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* _HAL_LLD_H_ */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c deleted file mode 100644 index 97befb19f..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/hal_st_lld.c - * @brief ST Driver subsystem low level driver code. - * - * @addtogroup ST - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/** - * @brief Periodic Interrupt Timer frequency. - */ -#define SAMA_PIT (SAMA_MCK / 16 / SAMA_H64MX_H32MX_RATIO) - -#if (SAMA_ST_USE_TC0 == TRUE) || (SAMA_ST_USE_TC1 == TRUE) -/** - * @brief Enable write protection on TC registers block. - * - * @param[in] tc pointer to a TC - * - * @notapi - */ -#define tcEnableWP(tc) { \ - tc->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on TC registers block. - * - * @param[in] tc pointer to a TC - * - * @notapi - */ -#define tcDisableWP(tc) { \ - tc->TC_WPMR = TC_WPMR_WPKEY_PASSWD; \ -} -#endif - -#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING - -#if SAMA_ST_USE_PIT -#error "PIT timer doesn't support tick-less mode" -#endif - -#if SAMA_ST_USE_TC0 -#if ((SAMA_TC0CLK) / (OSAL_ST_FREQUENCY) != 32) -#error "Bad OSAL_ST_FREQUENCY value in configuration. It must be set to TC0_periph_clk / 32" -#endif -#endif - -#if SAMA_ST_USE_TC1 -#if (((SAMA_TC1CLK) / (OSAL_ST_FREQUENCY) != 32) || ((SAMA_TC1CLK) % (OSAL_ST_FREQUENCY)) != 0) -#error "Bad OSAL_ST_FREQUENCY value in configuration. It must be set to TC1_periph_clk / 32" -#endif -#endif - -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -#if SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1 -static Tc *tcp; -#endif - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) || defined(__DOXYGEN__) -/** - * @brief System Timer vector. - * @details This interrupt is used both in periodic or free running - * mode, generated by TCx timer. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_ST_TC_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - (void)tcp->TC_CHANNEL[0].TC_SR; /* acknowledge TC interrupt */ - osalSysLockFromISR(); - osalOsTimerHandlerI(); - osalSysUnlockFromISR(); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if (SAMA_ST_USE_PIT) || defined(__DOXYGEN__) -/** - * @brief System Timer vector. - * @details This interrupt is used for system tick in periodic mode. - * - * @isr - */ -OSAL_IRQ_HANDLER(PIT_Handler) { - uint32_t ivr; - OSAL_IRQ_PROLOGUE(); - - osalSysLockFromISR(); - ivr = PIT->PIT_PIVR; /* acknowledge PIT interrupt */ - osalDbgAssert((ivr & PIT_PIVR_PICNT_Msk) == (1 << PIT_PIVR_PICNT_Pos), - "check for lost tick"); - osalOsTimerHandlerI(); - osalSysUnlockFromISR(); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* SAMA_ST_USE_PIT == TRUE */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level ST driver initialization. - * - * @notapi - */ -void st_lld_init(void) { - -#if SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1 - -#if SAMA_ST_USE_TC0 - tcp = TC0; - uint32_t rc = (SAMA_TC0CLK) / (OSAL_ST_FREQUENCY); - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TC0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - pmcEnableTC0(); - aicSetSourcePriority(ID_TC0, SAMA_TC0_IRQ_PRIORITY); - aicSetSourceHandler(ID_TC0, SAMA_ST_TC_HANDLER); - aicEnableInt(ID_TC0); -#endif - -#if SAMA_ST_USE_TC1 - tcp = TC1; - uint32_t rc = (SAMA_TC1CLK) / (OSAL_ST_FREQUENCY); - -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TC1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - pmcEnableTC1(); - aicSetSourcePriority(ID_TC1, SAMA_TC1_IRQ_PRIORITY); - aicSetSourceHandler(ID_TC1, SAMA_ST_TC_HANDLER); - aicEnableInt(ID_TC1); -#endif - - tcDisableWP(tcp); -#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING - - /* Initializing the timer counter in free running mode. - * The clock source is the bus clock divided by 32.*/ - (void)rc; - tcp->TC_CHANNEL[0].TC_EMR = 0; - tcp->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_WAVSEL_UP | - TC_CMR_TCCLKS(TC_CMR_TCCLKS_TIMER_CLOCK3); - tcp->TC_CHANNEL[0].TC_RC = 0; - tcp->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; - tcp->TC_CHANNEL[0].TC_IDR = 0xFFFFFFFF; /* Disable IRQs. */ - tcp->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */ -#endif - -#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC - tcp->TC_CHANNEL[0].TC_EMR = TC_EMR_NODIVCLK; - tcp->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC; - tcp->TC_CHANNEL[0].TC_RC = TC_RC_RC(rc); - tcp->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;; - tcp->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */ - tcp->TC_CHANNEL[0].TC_IER = TC_IER_CPCS; -#endif - - tcEnableWP(tcp); -#endif /* SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1 */ - -#if (SAMA_ST_USE_PIT == TRUE) -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_PIT, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - /* Enable PIT.*/ - pmcEnablePIT(); - PIT->PIT_MR = PIT_MR_PIV((SAMA_PIT / OSAL_ST_FREQUENCY) - 1); - PIT->PIT_MR |= PIT_MR_PITEN | PIT_MR_PITIEN; - (void) PIT->PIT_PIVR; /* reset PIT PICNT counter */ - - /* Enable IRQ.*/ - aicSetSourcePriority(ID_PIT, SAMA_ST_IRQ_PRIORITY); - aicSetSourceHandler(ID_PIT, PIT_Handler); - aicEnableInt(ID_PIT); -#endif /* SAMA_ST_USE_PIT */ - -} - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h deleted file mode 100644 index 3325d4ac8..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/hal_st_lld.h - * @brief ST Driver subsystem low level driver header. - * @details This header is designed to be include-able without having to - * include other files from the HAL. - * - * @addtogroup ST - * @{ - */ - -#ifndef HAL_ST_LLD_H -#define HAL_ST_LLD_H - -#include "mcuconf.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief SysTick timer IRQ priority. - */ -#if !defined(SAMA_ST_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_ST_IRQ_PRIORITY 0 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ -/* Only one source for st */ -#if SAMA_ST_USE_TC0 -#if defined(ST_ASSIGNED) -#error "ST already assigned" -#else -#define ST_ASSIGNED -#endif -#endif - -/* Only one source for st */ -#if SAMA_ST_USE_TC1 -#if defined(ST_ASSIGNED) -#error "ST already assigned" -#else -#define ST_ASSIGNED -#endif -#endif - -/* Only one source for st */ -#if SAMA_ST_USE_PIT -#if defined(ST_ASSIGNED) -#error "ST already assigned" -#else -#define ST_ASSIGNED -#endif -#endif - -/* Checks on allocation of TCx units.*/ -#if SAMA_ST_USE_TC0 -#if defined(SAMA_TC0_IS_USED) -#error "ST requires TC0 but the peripheral is already used" -#else -#define SAMA_TC0_IS_USED -#endif -#endif - -#if SAMA_ST_USE_TC1 -#if defined(SAMA_TC1_IS_USED) -#error "ST requires TC1 but the peripheral is already used" -#else -#define SAMA_TC1_IS_USED -#endif -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void st_lld_init(void); -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Driver inline functions. */ -/*===========================================================================*/ - -/** - * @brief Returns the time counter value. - * - * @return The counter value. - * - * @notapi - */ -static inline systime_t st_lld_get_counter(void) { - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) - -#if SAMA_ST_USE_TC0 - - Tc *tcp = TC0; -#endif -#if SAMA_ST_USE_TC1 - - Tc *tcp = TC1; -#endif - - return (systime_t)tcp->TC_CHANNEL[0].TC_CV; -#else - - return (systime_t)0; -#endif -} - -/** - * @brief Starts the alarm. - * @note Makes sure that no spurious alarms are triggered after - * this call. - * - * @param[in] time the time to be set for the first alarm - * - * @notapi - */ -static inline void st_lld_start_alarm(systime_t time) { - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) - -#if SAMA_ST_USE_TC0 - - Tc *tcp = TC0; -#endif -#if SAMA_ST_USE_TC1 - - Tc *tcp = TC1; -#endif - - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD; - tcp->TC_CHANNEL[0].TC_RC = TC_RC_RC((uint32_t)time); - tcp->TC_CHANNEL[0].TC_SR; - tcp->TC_CHANNEL[0].TC_IER = TC_IER_CPCS; - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; -#else - - (void)time; -#endif -} - -/** - * @brief Stops the alarm interrupt. - * - * @notapi - */ -static inline void st_lld_stop_alarm(void) { - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) - -#if SAMA_ST_USE_TC0 - - Tc *tcp = TC0; -#endif -#if SAMA_ST_USE_TC1 - - Tc *tcp = TC1; -#endif - - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD; - tcp->TC_CHANNEL[0].TC_IDR = TC_IDR_CPCS; - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; -#endif -} - -/** - * @brief Sets the alarm time. - * - * @param[in] time the time to be set for the next alarm - * - * @notapi - */ -static inline void st_lld_set_alarm(systime_t time) { - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) - -#if SAMA_ST_USE_TC0 - - Tc *tcp = TC0; -#endif -#if SAMA_ST_USE_TC1 - - Tc *tcp = TC1; -#endif - - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD; - tcp->TC_CHANNEL[0].TC_RC = TC_RC_RC((uint32_t)time); - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; -#else - - (void)time; -#endif -} - -/** - * @brief Returns the current alarm time. - * - * @return The currently set alarm time. - * - * @notapi - */ -static inline systime_t st_lld_get_alarm(void) { - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) - -#if SAMA_ST_USE_TC0 - - Tc *tcp = TC0; -#endif -#if SAMA_ST_USE_TC1 - - Tc *tcp = TC1; -#endif - - return (systime_t)tcp->TC_CHANNEL[0].TC_RC; -#else - - return (systime_t)0; -#endif -} - -/** - * @brief Determines if the alarm is active. - * - * @return The alarm status. - * @retval false if the alarm is not active. - * @retval true is the alarm is active - * - * @notapi - */ -static inline bool st_lld_is_alarm_active(void) { - -#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) - -#if SAMA_ST_USE_TC0 - - Tc *tcp = TC0; -#endif -#if SAMA_ST_USE_TC1 - - Tc *tcp = TC1; -#endif - - return (bool)((tcp->TC_CHANNEL[0].TC_IMR & TC_IMR_CPCS) != 0); -#else - - return false; -#endif -} - -#endif /* HAL_ST_LLD_H */ - -/** @} */ - diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c deleted file mode 100644 index 26874472f..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/hal_tc_lld.c - * @brief SAMA TC support code. - * - * @addtogroup TC - * @{ - */ - -#include "hal.h" - -#if HAL_USE_TC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Enable write protection on TC registers block. - * - * @param[in] tcp pointer to a TC register block - * - * @notapi - */ -#define tcEnableWP(tcp) { \ - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on TC registers block. - * - * @param[in] tcp pointer to a TC register block - * - * @notapi - */ -#define tcDisableWP(tcp) { \ - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD; \ -} - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief TCD0 driver identifier. - * @note The driver TCD0 allocates the timer TC0 when enabled. - */ -#if SAMA_USE_TC0 || defined(__DOXYGEN__) -TCDriver TCD0; -#endif - -/** - * @brief TCD1 driver identifier. - * @note The driver TCD1 allocates the timer TC1 when enabled. - */ -#if SAMA_USE_TC1 || defined(__DOXYGEN__) -TCDriver TCD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Common IRQ handler. - * @note It is assumed that the various sources are only activated if the - * associated callback pointer is not equal to @p NULL in order to not - * perform an extra check in a potentially critical interrupt handler. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @notapi - */ -void tc_lld_serve_interrupt(TCDriver *tcp) { - uint32_t sr, imr, i; - - for (i = 0; i < TC_CHANNELS; i++) { - sr = tcp->tim->TC_CHANNEL[i].TC_SR; - imr = tcp->tim->TC_CHANNEL[i].TC_IMR; - if (((sr & TC_SR_CPCS) != 0) && ((imr & TC_IMR_CPCS) != 0) && - (tcp->config->channels[i].callback != NULL)) { - tcp->config->channels[i].callback(tcp); - } - } -} -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if SAMA_USE_TC0 || defined(__DOXYGEN__) -#if !defined(SAMA_TC0_SUPPRESS_ISR) -/** - * @brief TC0 interrupt handler. - * @note It is assumed that this interrupt is only activated if the callback - * pointer is not equal to @p NULL in order to not perform an extra - * check in a potentially critical interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_TC0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - tc_lld_serve_interrupt(&TCD0); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(SAMA_TC0_SUPPRESS_ISR) */ -#endif /* SAMA_USE_TC0 */ - -#if SAMA_USE_TC1 || defined(__DOXYGEN__) -#if !defined(SAMA_TC1_SUPPRESS_ISR) -/** - * @brief TC1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_TC1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - tc_lld_serve_interrupt(&TCD1); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(SAMA_TC1_SUPPRESS_ISR) */ -#endif /* SAMA_USE_TC1 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level TC driver initialization. - * - * @notapi - */ -void tc_lld_init(void) { - -#if SAMA_USE_TC0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TC0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - tcObjectInit(&TCD0); - TCD0.channels = TC_CHANNELS; - TCD0.tim = TC0; - TCD0.clock = SAMA_TC0CLK; -#endif - -#if SAMA_USE_TC1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TC1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - tcObjectInit(&TCD1); - TCD1.channels = TC_CHANNELS; - TCD1.tim = TC1; - TCD1.clock = SAMA_TC1CLK; -#endif - -} - -/** - * @brief Configures and activates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @notapi - */ -void tc_lld_start(TCDriver *tcp) { - uint32_t rc = 0; - - if (tcp->state == TC_STOP) { - /* Clock activation.*/ -#if SAMA_USE_TC0 - if (&TCD0 == tcp) { - pmcEnableTC0(); -#if !defined(SAMA_TC0_SUPPRESS_ISR) - aicSetSourcePriority(ID_TC0, SAMA_TC0_IRQ_PRIORITY); - aicSetSourceHandler(ID_TC0, SAMA_TC0_HANDLER); - aicEnableInt(ID_TC0); -#endif - } -#endif - -#if SAMA_USE_TC1 - if (&TCD1 == tcp) { - pmcEnableTC1(); -#if !defined(SAMA_TC1_SUPPRESS_ISR) - aicSetSourcePriority(ID_TC1, SAMA_TC1_IRQ_PRIORITY); - aicSetSourceHandler(ID_TC1, SAMA_TC1_HANDLER); - aicEnableInt(ID_TC1); -#endif - } -#endif - } - /* Disable Write Protection */ - tcDisableWP(tcp->tim); - /* Output enables*/ - switch (tcp->config->channels[0].mode & TC_OUTPUT_MASK) { - case TC_OUTPUT_ACTIVE: - rc = (tcp->clock) / (tcp->config->channels[0].frequency); - tcp->tim->TC_CHANNEL[0].TC_EMR = TC_EMR_NODIVCLK; - tcp->tim->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET | - TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC; - - tcp->tim->TC_CHANNEL[0].TC_RC = TC_RC_RC(rc); - tcp->tim->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */ - default: - ; - } - switch (tcp->config->channels[1].mode & TC_OUTPUT_MASK) { - case TC_OUTPUT_ACTIVE: - rc = (tcp->clock) / (tcp->config->channels[1].frequency); - tcp->tim->TC_CHANNEL[1].TC_EMR = TC_EMR_NODIVCLK; - tcp->tim->TC_CHANNEL[1].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET | - TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC; - - tcp->tim->TC_CHANNEL[1].TC_RC = TC_RC_RC(rc); - tcp->tim->TC_CHANNEL[1].TC_SR; /* Clear pending IRQs. */ - default: - ; - } - switch (tcp->config->channels[2].mode & TC_OUTPUT_MASK) { - case TC_OUTPUT_ACTIVE: - rc = (tcp->clock) / (tcp->config->channels[2].frequency); - tcp->tim->TC_CHANNEL[2].TC_EMR = TC_EMR_NODIVCLK; - tcp->tim->TC_CHANNEL[2].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET | - TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC; - - tcp->tim->TC_CHANNEL[2].TC_RC = TC_RC_RC(rc); - tcp->tim->TC_CHANNEL[2].TC_SR; /* Clear pending IRQs. */ - default: - ; - } - /* Enable Write Protection */ - tcEnableWP(tcp->tim); -} - -/** - * @brief Deactivates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @notapi - */ -void tc_lld_stop(TCDriver *tcp) { - - /* If in ready state then disables the TC clock.*/ - if (tcp->state == TC_READY) { -#if SAMA_USE_TC0 - if (&TCD0 == tcp) { - aicDisableInt(ID_TC0); - pmcDisableTC0(); - } -#endif - -#if SAMA_USE_TC1 - if (&TCD1 == tcp) { - aicDisableInt(ID_TC1); - pmcDisableTC1(); - } -#endif - } -} - -/** - * @brief Enables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is active using the specified configuration. - * @note The function has effect at the next cycle start. - * @note Channel notification is not enabled. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * @param[in] width TC pulse width as clock pulses number - * - * @notapi - */ -void tc_lld_enable_channel(TCDriver *tcp, - tcchannel_t channel, - tccnt_t width) { - /* Disable Write Protection */ - tcDisableWP(tcp->tim); - - /* Changing channel duty cycle on the fly.*/ - uint32_t rc = tcp->tim->TC_CHANNEL[channel].TC_RC; - tcp->tim->TC_CHANNEL[channel].TC_RA = TC_RA_RA((100 - width) * rc / 100); - tcp->tim->TC_CHANNEL[channel].TC_CCR = TC_CCR_CLKEN; - tcp->tim->TC_CHANNEL[channel].TC_CCR = TC_CCR_SWTRG; - - /* Enable Write Protection */ - tcEnableWP(tcp->tim); -} - -/** - * @brief Disables a TC channel and its notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is disabled and its output line returned to the - * idle state. - * @note The function has effect at the next cycle start. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @notapi - */ -void tc_lld_disable_channel(TCDriver *tcp, tcchannel_t channel) { - - tcp->tim->TC_CHANNEL[channel].TC_CCR = TC_CCR_CLKDIS; -} - -/** - * @brief Enables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already enabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @notapi - */ -void tc_lld_enable_channel_notification(TCDriver *tcp, - tcchannel_t channel) { - tcp->tim->TC_CHANNEL[channel].TC_IER |= TC_IER_CPCS; -} - -/** - * @brief Disables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already disabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @notapi - */ -void tc_lld_disable_channel_notification(TCDriver *tcp, - tcchannel_t channel) { - - tcp->tim->TC_CHANNEL[channel].TC_IDR |= TC_IDR_CPCS; -} - -/** - * @brief Changes TC channel's frequency. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel must be enabled using @p tcEnableChannel(). - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - */ - -void tcChangeChannelFrequency(TCDriver *tcp, - tcchannel_t channel,uint32_t frequency) { - tcDisableWP(tcp->tim); - uint32_t rc =(tcp->clock) / (frequency); - tcp->tim->TC_CHANNEL[channel].TC_RC = TC_RC_RC(rc); - tcEnableWP(tcp->tim); -} -/** - * @brief TC Driver initialization. - * - * @init - */ -void tcInit(void) { - - tc_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p TCDriver structure. - * - * @param[out] tcp pointer to a @p TCDriver object - * - * @init - */ -void tcObjectInit(TCDriver *tcp) { - - tcp->state = TC_STOP; - tcp->config = NULL; - tcp->enabled = 0; - tcp->channels = 0; -} - - -/** - * @brief Configures and activates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] config pointer to a @p TCConfig object - * - * @api - */ -void tcStart(TCDriver *tcp, const TCConfig *config) { - - osalDbgCheck((tcp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((tcp->state == TC_STOP) || (tcp->state == TC_READY), - "invalid state"); - tcp->config = config; - tc_lld_start(tcp); - tcp->enabled = 0; - tcp->state = TC_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @api - */ -void tcStop(TCDriver *tcp) { - - osalDbgCheck(tcp != NULL); - - osalSysLock(); - - osalDbgAssert((tcp->state == TC_STOP) || (tcp->state == TC_READY), - "invalid state"); - - tc_lld_stop(tcp); - tcp->enabled = 0; - tcp->config = NULL; - tcp->state = TC_STOP; - - osalSysUnlock(); -} - -/** - * @brief Enables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is active using the specified configuration. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * @param[in] width TC pulse width as clock pulses number - * - * @api - */ -void tcEnableChannel(TCDriver *tcp, - tcchannel_t channel, - tccnt_t width) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - - tcEnableChannelI(tcp, channel, width); - - osalSysUnlock(); -} - -/** - * @brief Disables a TC channel and its notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is disabled and its output line returned to the - * idle state. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @api - */ -void tcDisableChannel(TCDriver *tcp, tcchannel_t channel) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - - tcDisableChannelI(tcp, channel); - - osalSysUnlock(); -} - -/** - * @brief Enables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already enabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @api - */ -void tcEnableChannelNotification(TCDriver *tcp, tcchannel_t channel) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - osalDbgAssert((tcp->enabled & ((tcchnmsk_t)1U << (tcchnmsk_t)channel)) != 0U, - "channel not enabled"); - osalDbgAssert(tcp->config->channels[channel].callback != NULL, - "undefined channel callback"); - - tcEnableChannelNotificationI(tcp, channel); - - osalSysUnlock(); -} - -/** - * @brief Disables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already disabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @api - */ -void tcDisableChannelNotification(TCDriver *tcp, tcchannel_t channel) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - osalDbgAssert((tcp->enabled & ((tcchnmsk_t)1U << (tcchnmsk_t)channel)) != 0U, - "channel not enabled"); - osalDbgAssert(tcp->config->channels[channel].callback != NULL, - "undefined channel callback"); - - tcDisableChannelNotificationI(tcp, channel); - - osalSysUnlock(); -} - -#endif /* HAL_USE_TC */ - -/** @} */ - - - - diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.h deleted file mode 100644 index ec161b49c..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/hal_tc_lld.h - * @brief SAMA TC subsystem low level driver header. - * - * @addtogroup TC - * @{ - */ - -#ifndef HAL_TC_LLD_H -#define HAL_TC_LLD_H - -#if HAL_USE_TC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Number of TC channels per TC driver. - */ -#define TC_CHANNELS TCCHANNEL_NUMBER - -/** - * @name TC output mode macros - * @{ - */ -/** - * @brief Standard output modes mask. - */ -#define TC_OUTPUT_MASK 0x0FU - -/** - * @brief Output not driven, callback only. - */ -#define TC_OUTPUT_DISABLED 0x00U - -/** - * @brief Output active. - */ -#define TC_OUTPUT_ACTIVE 0x01U - -/** @} */ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Driver state machine possible states. - */ -typedef enum { - TC_UNINIT = 0, /**< Not initialized. */ - TC_STOP = 1, /**< Stopped. */ - TC_READY = 2 /**< Ready. */ -} tcstate_t; - -/** - * @brief Type of a structure representing a TC driver. - */ -typedef struct TCDriver TCDriver; - -/** - * @brief Type of a TC notification callback. - * - * @param[in] tcp pointer to a @p TCDriver object - */ -typedef void (*tccallback_t)(TCDriver *tcp); - - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief TCD0 driver enable switch. - * @details If set to @p TRUE the support for TCD0 is included. - * @note The default is @p TRUE. - */ -#if !defined(SAMA_USE_TC0) || defined(__DOXYGEN__) -#define SAMA_USE_TC0 FALSE -#endif - -/** - * @brief TCD1 driver enable switch. - * @details If set to @p TRUE the support for TCD1 is included. - * @note The default is @p TRUE. - */ -#if !defined(SAMA_USE_TC1) || defined(__DOXYGEN__) -#define SAMA_USE_TC1 FALSE -#endif - -/** - * @brief TCD0 interrupt priority level setting. - */ -#if !defined(SAMA_TC0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_TC0_IRQ_PRIORITY 2 -#endif - -/** - * @brief TCD1 interrupt priority level setting. - */ -#if !defined(SAMA_TC1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_TC1_IRQ_PRIORITY 2 -#endif - -/** @} */ - -/*===========================================================================*/ -/* Configuration checks. */ -/*===========================================================================*/ - -#if !SAMA_USE_TC0 && !SAMA_USE_TC1 -#error "TC driver activated but no TC peripheral assigned" -#endif - -/* Checks on allocation of TCx units.*/ -#if SAMA_USE_TC0 -#if defined(SAMA_TC0_IS_USED) -#error "TC0 is already used" -#else -#define SAMA_TC0_IS_USED -#endif -#endif - -/* Checks on allocation of TCx units.*/ -#if SAMA_USE_TC1 -#if defined(SAMA_TC1_IS_USED) -#error "TC1 is already used" -#else -#define SAMA_TC1_IS_USED -#endif -#endif -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of a TC mode. - */ -typedef uint32_t tcmode_t; - -/** - * @brief Type of a TC channel. - */ -typedef uint8_t tcchannel_t; - -/** - * @brief Type of a channels mask. - */ -typedef uint32_t tcchnmsk_t; - -/** - * @brief Type of a TC counter. - */ -typedef uint32_t tccnt_t; - -/** - * @brief Type of a TC driver channel configuration structure. - */ -typedef struct { - /** - * @brief Channel active logic level. - */ - tcmode_t mode; - /** - * @brief Timer clock in Hz. - * @note The low level can use assertions in order to catch invalid - * frequency specifications. - */ - uint32_t frequency; - /** - * @brief Channel callback pointer. - * @note This callback is invoked on the channel compare event. If set to - * @p NULL then the callback is disabled. - */ - tccallback_t callback; - /* End of the mandatory fields.*/ -} TCChannelConfig; - -/** - * @brief Type of a TC driver configuration structure. - */ -typedef struct { - /** - * @brief Channels configurations. - */ - TCChannelConfig channels[TC_CHANNELS]; - /* End of the mandatory fields.*/ -} TCConfig; - -/** - * @brief Structure representing a TC driver. - */ -struct TCDriver { - /** - * @brief Driver state. - */ - tcstate_t state; - /** - * @brief Current driver configuration data. - */ - const TCConfig *config; - /** - * @brief Mask of the enabled channels. - */ - tcchnmsk_t enabled; - /** - * @brief Number of channels in this instance. - */ - tcchannel_t channels; - /* End of the mandatory fields.*/ - /** - * @brief Timer base clock. - */ - uint32_t clock; - /** - * @brief Pointer to the TCx registers block. - */ - Tc *tim; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @brief Enables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is active using the specified configuration. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * @param[in] width TC pulse width as clock pulses number - * - * @iclass - */ -#define tcEnableChannelI(tcp, channel, width) do { \ - (tcp)->enabled |= ((tcchnmsk_t)1U << (tcchnmsk_t)(channel)); \ - tc_lld_enable_channel(tcp, channel, width); \ -} while (false) - -/** - * @brief Disables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is disabled and its output line returned to the - * idle state. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcDisableChannelI(tcp, channel) do { \ - (tcp)->enabled &= ~((tcchnmsk_t)1U << (tcchnmsk_t)(channel)); \ - tc_lld_disable_channel(tcp, channel); \ -} while (false) - -/** - * @brief Returns a TC channel status. - * @pre The TC unit must have been activated using @p tcStart(). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcIsChannelEnabledI(tcp, channel) \ - (((tcp)->enabled & ((tcchnmsk_t)1U << (tcchnmsk_t)(channel))) != 0U) - -/** - * @brief Enables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already enabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcEnableChannelNotificationI(tcp, channel) \ - tc_lld_enable_channel_notification(tcp, channel) - -/** - * @brief Disables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already disabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcDisableChannelNotificationI(tcp, channel) \ - tc_lld_disable_channel_notification(tcp, channel) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if SAMA_USE_TC0 && !defined(__DOXYGEN__) -extern TCDriver TCD0; -#endif - -#if SAMA_USE_TC1 && !defined(__DOXYGEN__) -extern TCDriver TCD1; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void tcInit(void); - void tcObjectInit(TCDriver *tcp); - void tcStart(TCDriver *tcp, const TCConfig *config); - void tcStop(TCDriver *tcp); - void tcEnableChannel(TCDriver *tcp, - tcchannel_t channel, - tccnt_t width); - void tcDisableChannel(TCDriver *tcp, tcchannel_t channel); - void tcEnableChannelNotification(TCDriver *tcp, tcchannel_t channel); - void tcDisableChannelNotification(TCDriver *tcp, tcchannel_t channel); - void tcChangeChannelFrequency(TCDriver *tcp, tcchannel_t channel, uint32_t frequency); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_TC */ - -#endif /* HAL_TC_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/platform.mk b/os/hal/ports/SAMA/SAMA5D2x/platform.mk deleted file mode 100644 index 67f8976da..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/platform.mk +++ /dev/null @@ -1,47 +0,0 @@ -# Required platform files. - -PLATFORMSRC := $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_aic.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_classd.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_cache.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c - -# Required include directories. -PLATFORMINC := $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x - -# Optional platform files. -ifeq ($(USE_SMART_BUILD),yes) - -# Configuration files directory -ifeq ($(CONFDIR),) - CONFDIR = . -endif - -HALCONF := $(strip $(shell cat $(CONFDIR)/halconf.h | egrep -e "\#define")) - -else -endif - -# Drivers compatible with the platform. -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/DMAv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/I2Cv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/MACv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/PIOv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/QUADSPIv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/SPIv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/RTCv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/xWDGv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/SDMMCv1/driver.mk -include $(CHIBIOS)/os/hal/ports/SAMA/LLD/RNGv1/driver.mk - -# Shared variables -ALLCSRC += $(PLATFORMSRC) -ALLINC += $(PLATFORMINC) diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_aic.c b/os/hal/ports/SAMA/SAMA5D2x/sama_aic.c deleted file mode 100644 index e47336bb5..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_aic.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/aic.c - * @brief SAMA AIC support code. - * - * @addtogroup SAMA5D2x_AIC - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Enable write protection on AIC registers block. - * - * @param[in] aicp pointer to a AIC register block - * - * @notapi - */ -#define aicEnableWP(aicp) { \ - aicp->AIC_WPMR = AIC_WPMR_WPKEY_PASSWD | AIC_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on AIC registers block. - * - * @param[in] aicp pointer to a AIC register block - * - * @notapi - */ -#define aicDisableWP(aicp) { \ - aicp->AIC_WPMR = AIC_WPMR_WPKEY_PASSWD; \ -} - -/** - * @brief Checks if a IRQ priority is within the valid range. - * @param[in] prio IRQ priority - * - * @retval The check result. - * @retval FALSE invalid IRQ priority. - * @retval TRUE correct IRQ priority. - */ -#define SAMA_IRQ_IS_VALID_PRIORITY(prio) ((prio) <= 7U) - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -static OSAL_IRQ_HANDLER(aicSpuriousHandler) { - OSAL_IRQ_PROLOGUE(); - osalSysHalt("Spurious interrupt"); - OSAL_IRQ_EPILOGUE(); -} - -static OSAL_IRQ_HANDLER(aicUnexpectedHandler) { - OSAL_IRQ_PROLOGUE(); - osalSysHalt("Unexpected interrupt"); - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief AIC Initialization. - * @note Better reset everything in the AIC. - * - * @notapi - */ -void aicInit(void) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - aicDisableWP(aic); - - aic->AIC_SPU = (uint32_t)aicSpuriousHandler; - aic->AIC_SSR = 0; - aic->AIC_SVR = (uint32_t)aicUnexpectedHandler; - - unsigned i; - /* Disable all interrupts */ - for (i = 1; i < ID_PERIPH_COUNT; i++) { - aic->AIC_SSR = i; - aic->AIC_IDCR = AIC_IDCR_INTD; - - /* Changes type */ - aic->AIC_SMR = AIC_SMR_SRCTYPE(EXT_NEGATIVE_EDGE); - - /* Clear pending interrupt */ - aic->AIC_ICCR = AIC_ICCR_INTCLR; - - /* Changes type */ - aic->AIC_SMR = AIC_SMR_SRCTYPE(INT_LEVEL_SENSITIVE); - - /* Default handler */ - aic->AIC_SVR = (uint32_t)aicUnexpectedHandler; - } - aicEnableWP(aic); -} - -/** - * @brief Configures an interrupt in the AIC. - * @note Source cannot be ID_SAIC_FIQ (0). - * - * @param[in] source interrupt source to configure - * @param[in] priority priority level of the selected source. - */ -void aicSetSourcePriority(uint32_t source, uint8_t priority) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - osalDbgCheck(source != ID_SAIC_FIQ); - osalDbgAssert(SAMA_IRQ_IS_VALID_PRIORITY(priority), "invalid irq priority"); - /* Disable write protection */ - aicDisableWP(aic); - /* Set source id */ - aic->AIC_SSR = source; - /* Disable the interrupt first */ - aic->AIC_IDCR = AIC_IDCR_INTD; - /* Configure priority */ - aic->AIC_SMR |= AIC_SMR_PRIOR(priority); - /* Clear interrupt */ - aic->AIC_ICCR = AIC_ICCR_INTCLR; - /* Enable write protection */ - aicEnableWP(aic); -} - -/** - * @brief Configures type of interrupt in the AIC. - * - * @param[in] source interrupt source to configure - * @param[in] type type interrupt of the selected source. - */ -void aicSetIntSourceType(uint32_t source, uint8_t type) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - /* Disable write protection */ - aicDisableWP(aic); - /* Set source id */ - aic->AIC_SSR = source; - /* Disable the interrupt first */ - aic->AIC_IDCR = AIC_IDCR_INTD; - /* Configure priority */ - aic->AIC_SMR |= AIC_SMR_SRCTYPE(type); - /* Clear interrupt */ - aic->AIC_ICCR = AIC_ICCR_INTCLR; - /* Enable write protection */ - aicEnableWP(aic); -} - -/** - * @brief Sets the source handler of an interrupt. - * - * @param[in] source interrupt source to configure - * @param[in] handler handler for the interrupt source selected - */ -void aicSetSourceHandler(uint32_t source, bool (*handler)(void)) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - /* Disable write protection */ - aicDisableWP(aic); - /* Select source and assign handler */ - aic->AIC_SSR = AIC_SSR_INTSEL(source); - aic->AIC_SVR = (uint32_t)handler; - /* Enable write protection */ - aicEnableWP(aic); -} - -/** - * @brief Sets the spurious handler of an interrupt. - * - * @param[in] handler handler for the interrupt - */ -void aicSetSpuriousHandler(bool (*handler)(void)) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - /* Disable write protection */ - aicDisableWP(aic); - /* Assign handler */ - aic->AIC_SPU = (uint32_t)handler; - /* Enable write protection */ - aicEnableWP(aic); -} - -/** - * @brief Enables interrupts coming from the source. - * - * @param[in] source interrupt source to enable - */ -void aicEnableInt(uint32_t source) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - aic->AIC_SSR = AIC_SSR_INTSEL(source); - aic->AIC_IECR = AIC_IECR_INTEN; -} - -/** - * @brief Disables interrupts coming from the selected source. - * - * @param[in] source interrupt source to disable - */ -void aicDisableInt(uint32_t source) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - aic->AIC_SSR = AIC_SSR_INTSEL(source); - aic->AIC_IDCR = AIC_IDCR_INTD; -} - -/** - * @brief Clears interrupts coming from the selected source. - * - * @param[in] source interrupt source to Clear - */ -void aicClearInt(uint32_t source) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - aic->AIC_SSR = AIC_SSR_INTSEL(source); - aic->AIC_ICCR = AIC_ICCR_INTCLR; -} - -/** - * @brief Sets interrupts coming from the selected source. - * - * @param[in] source interrupt source to Set - */ -void aicSetInt(uint32_t source) { - -#if SAMA_HAL_IS_SECURE - Aic *aic = SAIC; -#else - Aic *aic = AIC; -#endif - - aic->AIC_SSR = AIC_SSR_INTSEL(source); - aic->AIC_ISCR = AIC_ISCR_INTSET; -} - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_aic.h b/os/hal/ports/SAMA/SAMA5D2x/sama_aic.h deleted file mode 100644 index a4f220754..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_aic.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/aic.h - * @brief SAMA AIC support macros and structures. - * - * @addtogroup SAMA5D2x_AIC - * @{ - */ - -#ifndef AIC_H -#define AIC_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ -/** - * @name INTERRUPT SOURCE TYPE mode macros - * @{ - */ -/** - * @brief High-level sensitive for internal source. - * Low-level sensitive for external source. - */ -#define INT_LEVEL_SENSITIVE 0x0U - -/** - * @brief Negative-edge triggered for external source. - */ -#define EXT_NEGATIVE_EDGE 0x1U - -/** - * @brief High-level sensitive for internal source. - * High-level sensitive for external source. - */ -#define EXT_HIGH_LEVEL 0x2U - -/** - * @brief Positive-edge triggered for external source. - */ -#define EXT_POSITIVE_EDGE 0x3U -/** @} */ - -/** - * @brief AIC unique redirect key. - */ -#define AIC_REDIR_KEY 0x5B6C0E26U - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Acknowledge the current interrupt. - */ -#if SAMA_HAL_IS_SECURE -#define aicAckInt() { \ - SAIC->AIC_EOICR = AIC_EOICR_ENDIT; \ -} -#else -#define aicAckInt() { \ - AIC->AIC_EOICR = AIC_EOICR_ENDIT; \ -} -#endif - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void aicInit(void); - void aicSetSourcePriority(uint32_t source, uint8_t priority); - void aicSetIntSourceType(uint32_t source, uint8_t type); - void aicSetSourceHandler(uint32_t source, bool (*handler)(void)); - void aicSetSpuriousHandler(bool (*handler)(void)); - void aicEnableInt(uint32_t source); - void aicDisableInt(uint32_t source); - void aicClearInt(uint32_t source); - void aicSetInt(uint32_t source); -#ifdef __cplusplus -} -#endif - -#endif /* AIC_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_cache.c b/os/hal/ports/SAMA/SAMA5D2x/sama_cache.c deleted file mode 100644 index 0ed58a887..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_cache.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_cache.c - * @brief SAMA CACHE support code. - * - * @addtogroup SAMA5D2x_CACHE - * @{ - */ - -#include "hal.h" - -#if !defined(SAMA_L2CC_ASSUME_ENABLED) -#define SAMA_L2CC_ASSUME_ENABLED 0 -#endif - -#if !defined(SAMA_L2CC_ENABLE) -#define SAMA_L2CC_ENABLE 0 -#endif - -/** - * @brief Invalidate D-Cache Region - * - * @param[in] start Pointer to beginning of memory region. - * @param[in] length Length of the memory location. - */ -void cacheInvalidateRegion(void *start, uint32_t length) { - - uint32_t start_addr = (uint32_t)start; - uint32_t end_addr = start_addr + length; - uint32_t mva; - - /* Invalidate L1 D-Cache */ - for (mva = start_addr & ~(L1_CACHE_BYTES-1); mva < end_addr; mva += L1_CACHE_BYTES) { - L1C_InvalidateDCacheMVA((uint32_t *)mva); - } -#if ARM_SUPPORTS_L2CC -#if SAMA_L2CC_ASSUME_ENABLED || SAMA_L2CC_ENABLE - /* Invalidate L2 Cache */ - for (mva = start_addr & ~(L2_CACHE_BYTES-1); mva < end_addr; mva += L2_CACHE_BYTES) { - L2C_InvPa((uint32_t *)mva); - } -#endif -#endif -} - -/** - * @brief Clean D-Cache Region - * - * @param[in] start Pointer to beginning of memory region. - * @param[in] length Length of the memory location. - */ -void cacheCleanRegion(void *start, uint32_t length) { - - uint32_t start_addr = (uint32_t)start; - uint32_t end_addr = start_addr + length; - uint32_t mva; - - /* Clean L1 D-Cache */ - for (mva = start_addr & ~(L1_CACHE_BYTES-1); mva < end_addr; mva += L1_CACHE_BYTES) { - L1C_CleanDCacheMVA((uint32_t *)mva); - } -#if ARM_SUPPORTS_L2CC -#if SAMA_L2CC_ASSUME_ENABLED || SAMA_L2CC_ENABLE - /* Invalidate L2 Cache */ - for (mva = start_addr & ~(L2_CACHE_BYTES-1); mva < end_addr; mva += L2_CACHE_BYTES) { - L2C_CleanPa((uint32_t *)mva); - } -#endif -#endif -} - -/** - * @brief Clean and Invalidate D-Cache Region - * - * @param[in] start Pointer to beginning of memory region. - * @param[in] length Length of the memory location. - */ -void cacheCleanInvalidateRegion(void *start, uint32_t length) { - - uint32_t start_addr = (uint32_t)start; - uint32_t end_addr = start_addr + length; - uint32_t mva; - - /* Clean L1 D-Cache */ - for (mva = start_addr & ~(L1_CACHE_BYTES-1); mva < end_addr; mva += L1_CACHE_BYTES) { - L1C_CleanInvalidateDCacheMVA((uint32_t *)mva); - } -#if ARM_SUPPORTS_L2CC -#if SAMA_L2CC_ASSUME_ENABLED || SAMA_L2CC_ENABLE - /* Invalidate L2 Cache */ - for (mva = start_addr & ~(L2_CACHE_BYTES-1); mva < end_addr; mva += L2_CACHE_BYTES) { - L2C_CleanInvPa((uint32_t *)mva); - } -#endif -#endif -} - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_cache.h b/os/hal/ports/SAMA/SAMA5D2x/sama_cache.h deleted file mode 100644 index 25be583ff..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_cache.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_cache.h - * @brief SAMA CACHE support macros and structures. - * - * @addtogroup SAMA5D2x_CACHE - * @{ - */ -#ifndef SAMA_CACHE_H_ -#define SAMA_CACHE_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ -#define L1_CACHE_BYTES 32u -#define L2_CACHE_BYTES 32u - -#define CACHE_ALIGNED ALIGNED_VAR(L1_CACHE_BYTES) -#define NO_CACHE __attribute__((section (".nocache"))) - - -#ifdef __cplusplus -extern "C" { -#endif - extern void cacheInvalidateRegion(void *start, uint32_t length); - extern void cacheCleanRegion(void *start, uint32_t length); - extern void cacheCleanInvalidateRegion(void *start, uint32_t length); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_CACHE_H_ */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_classd.c b/os/hal/ports/SAMA/SAMA5D2x/sama_classd.c deleted file mode 100644 index 37a3ce689..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_classd.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_classd.c - * @brief SAMA CLASSD support code. - * - * @addtogroup SAMA5D2x_CLASSD - * @{ - */ - -#include "hal.h" - -#if SAMA_USE_CLASSD || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Enable write protection on CLASSD Mode Register - * and Interpolator Mode Register. - * - * @param[in] classdp pointer to a CLASSD register block - * - * @notapi - */ -#define classdEnableWP(classdp) { \ - classdp->CLASSD_WPMR = CLASSD_WPMR_WPKEY_PASSWD | CLASSD_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on CLASSD Mode Register - * and Interpolator Mode Register. - * - * @param[in] classdp pointer to a CLASSD register block - * - * @notapi - */ -#define classdDisableWP(classdp) { \ - classdp->CLASSD_WPMR = CLASSD_WPMR_WPKEY_PASSWD; \ -} - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -/** - * @brief CLASSD driver identifier. - */ -CLASSDDriver CLASSDD0; - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ -/** - * @brief Type of a structure representing PMC Audio configuration. - */ -typedef struct { - /** - * @brief Loop Divider Ratio. - */ - uint32_t nd; - - /** - * @brief Fractional Loop Divider Setting. - */ - uint32_t fracr; - - /** - * @brief Output Divider Ratio for PMC Clock. - */ - uint32_t qdpmc; - - /** - * @brief Divider Value. - */ - uint32_t div; - - /** - * @brief Output Divider Ratio for Pad Clock. - */ - uint32_t qdaudio; -} pmcAudioConf; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Configure DSPClock. - * - * @param[in] dsp_clk DSP clock type (12.288 MHz or 11.2896 MHz). - */ -static void dspclkConfigure(uint32_t dsp_clk) { - pmcAudioConf cfg; - - /* Pad Clock: not used */ - cfg.div = 0; - cfg.qdaudio = 0; - - /* PMC Clock: */ - /* 12Mhz * (ND + 1 + FRACR/2^22) / (QDPMC + 1) = 8 * DSPCLK */ - switch (dsp_clk) { - case CLASSD_INTPMR_DSPCLKFREQ_12M288: -#if SAMA_MOSCXTCLK == 12000000 - /* 12Mhz * (56 + 1 + 1442841/2^22) / (6 + 1) = 8 * 12.288Mhz */ - cfg.nd = 56; - cfg.fracr = 1442841; - cfg.qdpmc = 6; -#elif SAMA_MOSCXTCLK == 24000000 - /* 24Mhz * (56 + 1 + 1442841/2^22) / (6 + 1) = 8 * 12.288Mhz */ - cfg.nd = 27; - cfg.fracr = 2796203; - cfg.qdpmc = 6; -#else - #error "FREQUENCY NOT SUPPORTED BY CLASSD" -#endif - break; - - case CLASSD_INTPMR_DSPCLKFREQ_11M2896: -#if SAMA_MOSCXTCLK == 12000000 - /* 12Mhz * (59 + 1 + 885837/2^22) / (7 + 1) = 8 * 11.2896Mhz */ - cfg.nd = 59; - cfg.fracr = 885837; - cfg.qdpmc = 7; -#elif SAMA_MOSCXTCLK == 24000000 - /* 24Mhz * (59 + 1 + 885837/2^22) / (7 + 1) = 8 * 11.2896Mhz */ - cfg.nd = 28; - cfg.fracr = 699050; - cfg.qdpmc = 7; -#else - #error "FREQUENCY NOT SUPPORTED BY CLASSD" -#endif - break; - - default: - osalDbgAssert(NULL, "errore mask configuration"); - } - - /* Configure and enable the generic clock. */ - pmcConfigAudio(cfg.nd, cfg.qdpmc, cfg.fracr, cfg.div, cfg.qdaudio); - pmcEnableAudio(true, false); -} - -/** - * @brief Shared end-of-tx service routine. - * - * @param[in] classdp pointer to the @p CLASSDDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void classd_lld_serve_tx_interrupt(CLASSDDriver *classdp, uint32_t flags) { - - /* DMA errors handling.*/ -#if defined(SAMA_CLASSD_DMA_ERROR_HOOK) - (void)classdp; - if ((flags & (XDMAC_CIS_WBEIS | XDMAC_CIS_ROIS)) != 0) { - SAMA_CLASSD_DMA_ERROR_HOOK(classdp); - } -#else - (void)flags; -#endif - - if(classdp->config->callback != NULL) { - classdp->config->callback(classdp); - } - classdMuteChannel(classdp, false, false); - classdp->state = CLASSD_READY; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level CLASSD driver initialization. - * - * @notapi - */ -void classd_lld_init(void) { -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_CLASSD, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization. */ - classdObjectInit(&CLASSDD0); - CLASSDD0.classd = CLASSD; - CLASSDD0.dmatx = NULL; - CLASSDD0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | - XDMAC_CC_MBSIZE_SINGLE | - XDMAC_CC_DSYNC_MEM2PER | - XDMAC_CC_PROT_SEC | - XDMAC_CC_CSIZE_CHK_1 | - XDMAC_CC_DWIDTH_WORD | - XDMAC_CC_SIF_AHB_IF0 | - XDMAC_CC_DIF_AHB_IF1 | - XDMAC_CC_SAM_INCREMENTED_AM | - XDMAC_CC_DAM_FIXED_AM | - XDMAC_CC_PERID(PERID_CLASSD_TX); -} - -/** - * @brief Configures and activates the CLASSD peripheral. - * - * @param[in] classdp pointer to the @p CLASSDDriver object - * - * @notapi - */ -void classd_lld_start(CLASSDDriver *classdp) { - - uint8_t i; - uint32_t dsp_clk_set, frame_set; - - /* Configures the peripheral.*/ - if (classdp->state == CLASSD_STOP) { - - if (&CLASSDD0 == classdp) { - classdp->dmatx = dmaChannelAllocate(SAMA_CLASSD_DMA_IRQ_PRIORITY, - (sama_dmaisr_t)classd_lld_serve_tx_interrupt, - (void *)classdp); - osalDbgAssert(classdp->dmatx != NULL, "no channel allocated"); - } - } - - /* Set DMA channel mode. */ - dmaChannelSetMode(classdp->dmatx, classdp->txdmamode); - - /* Set CLASSD DSP clock and Sample rate. */ - for(i = 0; i < 8; i++) { - if ((audio_info[i].rate) == (classdp->config->frame)) { - dsp_clk_set = audio_info[i].dsp_clk; - frame_set = audio_info[i].sample_rate; - break; - } - } - - /* Enable the CLASSD0 clock. */ - pmcEnableCLASSD0(); - - /* Configure PMC Audio structure. */ - dspclkConfigure(dsp_clk_set); - - /* Disable the CLASSD generic clock for now. */ - pmcDisableGclkCLASSD0(); - - /* Configure the CLASSD generic clock */ - pmcConfigGclk(ID_CLASSD, PMC_PCR_GCKCSS_AUDIO_CLK, 1); - - /* Disable write protection. */ - classdDisableWP(classdp->classd); - - /* Perform soft reset. */ - CLASSD->CLASSD_CR = CLASSD_CR_SWRST; - CLASSD->CLASSD_IDR = CLASSD_IDR_DATRDY; - - /* Clean CLASSD Registers. */ - classdp->classd->CLASSD_MR = 0; - classdp->classd->CLASSD_INTPMR = 0; - - /* CLASSD configuration. */ - classdp->classd->CLASSD_MR = classdp->config->left | - classdp->config->right | - classdp->config->left_mute | - classdp->config->right_mute | - classdp->config->pwm_mode | - classdp->config->non_overlap | - classdp->config->novrval; - - classdp->classd->CLASSD_INTPMR = classdp->config->attl | - classdp->config->attr | - classdp->config->deemp | - classdp->config->swap | - classdp->config->eqcfg | - classdp->config->mono | - classdp->config->mono_mode | - dsp_clk_set | frame_set; - - /* Enable CLASSD generic clock. */ - pmcEnableGclkCLASSD0(); - - /* Enable write protection. */ - classdEnableWP(classdp->classd); -} - -/** - * @brief Deactivates the CLASSD peripheral. - * - * @param[in] classdp pointer to the @p CLASSDDriver object - * - * @notapi - */ -void classd_lld_stop(CLASSDDriver *classdp) { - - /* Disable clocks. */ - pmcDisableAudio(); - pmcDisableGclkCLASSD0(); - pmcDisableCLASSD0(); - - /* Disable write protection. */ - classdDisableWP(classdp->classd); - - /* Reset CLASSD. */ - classdp->classd->CLASSD_INTPMR = 0; - classdp->classd->CLASSD_MR = 0; - - /* Enable write protection. */ - classdEnableWP(classdp->classd); - - /* Release and disable DMA channel. */ - dmaChannelRelease(classdp->dmatx); -} - -/** - * - * @brief Starts a CLASSD playback. - * - * @param[in] classdp pointer to the @p CLASSDDriver - * @param[in] txbuf the pointer to the transmit buffer - * - * @notapi - */ -void classd_lld_send_audio(CLASSDDriver *classdp, const void *txbuf) { - - /* Get DMA transfert size. */ - size_t n = ((struct wav_header *)txbuf)->subchunk2_size / 4; - - osalDbgAssert(!((uint32_t) txbuf & (L1_CACHE_BYTES - 1)), "address not cache aligned"); - -#if 0 - osalDbgAssert(!(n & (L1_CACHE_BYTES - 1)), "size not multiple of cache line"); -#endif - - /* L1 is enabled */ - cacheCleanRegion((uint8_t *) txbuf, n); - - /* Get source address. */ - uint32_t addrSource = sizeof(struct wav_header); - - /* Unmute left and right channel */ - classdMuteChannel(classdp, false, false); - - /* Writing channel */ - dmaChannelSetSource(classdp->dmatx, txbuf + addrSource); - dmaChannelSetDestination(classdp->dmatx, &classdp->classd->CLASSD_THR); - dmaChannelSetTransactionSize(classdp->dmatx, n); - - /* DMA start transfer. */ - dmaChannelEnable(classdp->dmatx); -} - -/** - * @brief CLASSD mute/unmute channels. - * - * @param[in] classdp pointer to the @p CLASSDDriver object - * - * @iclass - */ -void classd_mute_channel(CLASSDDriver *classdp, bool left, bool right) { - - /* Disable write protection. */ - classdDisableWP(classdp->classd); - - /* Mute or unmute left channel. */ - if (left) - classdp->classd->CLASSD_MR |= CLASSD_MR_LMUTE; - else - classdp->classd->CLASSD_MR &= ~CLASSD_MR_LMUTE; - - /* Mute or unmute right channel. */ - if (right) - classdp->classd->CLASSD_MR |= CLASSD_MR_RMUTE; - else - classdp->classd->CLASSD_MR &= ~CLASSD_MR_RMUTE; - - /* Enable write protection. */ - classdEnableWP(classdp->classd); -} - -/** - * - * @brief CLASSD Driver initialization. - * - * @init - */ -void classdInit(void) { - - classd_lld_init(); -} - -/** - * - * @brief Initializes the standard part of a @p CLASSDDriver structure. - * - * @param[out] classdp pointer to a @p CLASSDDriver object - * - * @init - */ -void classdObjectInit(CLASSDDriver *classdp) { - classdp->state = CLASSD_STOP; - classdp->config = NULL; -} - -/** - * @brief Configures and activates the CLASSD peripheral. - * - * @param[in] classdp pointer to a @p CLASSDDriver object - * @param[in] config pointer to a @p CLASSDConfig object - * - * @api - */ -void classdStart(CLASSDDriver *classdp, const CLASSDConfig *config) { - - osalDbgCheck((classdp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((classdp->state == CLASSD_STOP) || (classdp->state == CLASSD_READY), - "invalid state"); - classdp->config = config; - classd_lld_start(classdp); - classdp->state = CLASSD_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the CLASSD peripheral. - * - * @param[in] classdp pointer to the @p CLASSDDriver object - * - * @api - */ -void classdStop(CLASSDDriver *classdp) { - - osalDbgCheck(classdp != NULL); - - osalSysLock(); - - osalDbgAssert((classdp->state == CLASSD_STOP) || (classdp->state == CLASSD_READY || (classdp->state == CLASSD_ACTIVE)), - "invalid state"); - - classd_lld_stop(classdp); - classdp->config = NULL; - classdp->state = CLASSD_STOP; - - osalSysUnlock(); -} - -/** - * - * @brief Starts a CLASSD playback. - * - * @param[in] classdp pointer to the @p CLASSDDriver - * @param[in] txbuf the pointer to the transmit buffer - * - * @note This function can be used only in syslock state. todo: control comment! - * - * @notapi - */ -void classdSendAudioI(CLASSDDriver *classdp, const void *txbuf) { - - (classdp)->state = CLASSD_ACTIVE; - classd_lld_send_audio(classdp, txbuf); -} - -/** - * - * @brief Starts a CLASSD playback. - * - * @param[in] classdp pointer to the @p CLASSDDriver - * @param[in] txbuf the pointer to the transmit buffer - * - * @notapi - */ -void classdSendAudio(CLASSDDriver *classdp, const void *txbuf) { - - osalSysLock(); - osalDbgAssert(classdp->state == CLASSD_READY, "not ready"); - classdSendAudioI(classdp, txbuf); - osalSysUnlock(); -} - -/** - * - * @brief Set the sample frame from the structure of a wav file. - * - * @param[in] classdconfigp pointer to the @p CLASSDConfig - * @param[in] music_file pointer to the wav file - * - * @notapi - */ -void classdSetSampleFrame(CLASSDConfig *classdconfigp, uint8_t *music_file) { - classdconfigp->frame = ((struct wav_header*)music_file)->sample_rate; -} - -/** - * @brief Mute/unmute CLASSD channel. - * - * @param[in] classdp pointer to the @p CLASSDDriver object - * - * @iclass - */ -void classdMuteChannel(CLASSDDriver *classdp, bool left, bool right) { - classd_mute_channel(classdp, left, right); -} - -#endif /* SAMA_USE_CLASSD */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_classd.h b/os/hal/ports/SAMA/SAMA5D2x/sama_classd.h deleted file mode 100644 index 212e4fab6..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_classd.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_classd.h - * @brief SAMA CLASSD support macros and structures. - * - * @addtogroup SAMA5D2x_CLASSD - * @{ - */ - -#ifndef SAMA_CLASSD_LLD_H -#define SAMA_CLASSD_LLD_H - -/** - * @brief Using the CLASSD driver. - */ -#if !defined(SAMA_USE_CLASSD) || defined(__DOXYGEN__) -#define SAMA_USE_CLASSD FALSE -#endif - -#if SAMA_USE_CLASSD || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ - -/** - * @brief CLASSD DMA interrupt priority level setting. - */ -#if !defined(SAMA_CLASSD_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_CLASSD_DMA_IRQ_PRIORITY 4 -#endif - -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if !defined(SAMA_DMA_REQUIRED) -#define SAMA_DMA_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Driver state machine possible states. - */ -typedef enum { - CLASSD_UNINIT = 0, /**< Not initialized. */ - CLASSD_STOP = 1, /**< Stopped. */ - CLASSD_READY = 2, /**< Ready. */ - CLASSD_ACTIVE = 3, /**< Exchanging data. */ -} classdstate_t; - -/** - * @brief Structure representing audio info. - */ -static const struct { - /** - * @brief Contains the value of the Sample Rate. - */ - uint32_t rate; - /** - * @brief Contains a mask of the Sample Rate. - */ - uint32_t sample_rate; - /** - * @brief Contains a mask of the DSP Clock. - */ - uint32_t dsp_clk; -} audio_info[] = { - {8000, CLASSD_INTPMR_FRAME_FRAME_8K, CLASSD_INTPMR_DSPCLKFREQ_12M288}, - {16000, CLASSD_INTPMR_FRAME_FRAME_16K, CLASSD_INTPMR_DSPCLKFREQ_12M288}, - {32000, CLASSD_INTPMR_FRAME_FRAME_32K, CLASSD_INTPMR_DSPCLKFREQ_12M288}, - {48000, CLASSD_INTPMR_FRAME_FRAME_48K, CLASSD_INTPMR_DSPCLKFREQ_12M288}, - {96000, CLASSD_INTPMR_FRAME_FRAME_96K, CLASSD_INTPMR_DSPCLKFREQ_12M288}, - {22050, CLASSD_INTPMR_FRAME_FRAME_22K, CLASSD_INTPMR_DSPCLKFREQ_11M2896}, - {44100, CLASSD_INTPMR_FRAME_FRAME_44K, CLASSD_INTPMR_DSPCLKFREQ_11M2896}, - {88200, CLASSD_INTPMR_FRAME_FRAME_88K, CLASSD_INTPMR_DSPCLKFREQ_11M2896}, -}; - -/** - * @brief Type of a structure representing Standard WAV file header information. - */ -struct wav_header { - /** - * @brief Contains the letters "RIFF" in ASCII form. - */ - uint32_t chunk_id; - /** - * @brief Size of the rest of the chunk following this number. - */ - uint32_t chunk_size; - /** - * @brief Contains the letters "WAVE". - */ - uint32_t format; - /** - * @brief Contains the letters "fmt ". - */ - uint32_t subchunk1_id; - /** - * @brief 16 for PCM. This is the size of the rest of the Subchunk which follows this number. - */ - uint32_t subchunk1_size; - /** - * @brief PCM = 1 (i.e. Linear quantization). Values other than 1 indicate some form of compression. - */ - uint16_t audio_format; - /** - * @brief Mono = 1, Stereo = 2, etc. - */ - uint16_t num_channels; - /** - * @brief 8000, 44100, etc. - */ - uint32_t sample_rate; - /** - * @brief SampleRate * NumChannels * BitsPerSample/8 - */ - uint32_t byte_rate; - /** - * @brief NumChannels * BitsPerSample/8 - */ - uint16_t block_align; - /** - * @brief 8 bits = 8, 16 bits = 16, etc. - */ - uint16_t bits_per_sample; - /** - * @brief Contains the letters "data". - */ - uint32_t subchunk2_id; - /** - * @brief Number of bytes in the data. - */ - uint32_t subchunk2_size; -}; - -/** - * @brief Type of a structure representing an CLASSD driver. - */ -typedef struct CLASSDDriver CLASSDDriver; - -/** - * @brief Type of a generic CLASSD callback. - */ -typedef void (*classdcb_t)(CLASSDDriver *classdp); - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief Callback pointer. - */ - classdcb_t callback; - /** - * @brief Configuration of the CLASSD left channel. - */ - uint32_t left; - /** - * @brief Configuration of the CLASSD right channel. - */ - uint32_t right; - /** - * @brief Configuration of the CLASSD left channel mute. - */ - uint32_t left_mute; - /** - * @brief Configuration of the CLASSD right channel mute. - */ - uint32_t right_mute; - /** - * @brief Configuration of the CLASSD PWM modulation type. - */ - uint32_t pwm_mode; - /** - * @brief Configuration of the CLASSD Non-Overlapping. - */ - uint32_t non_overlap; - /** - * @brief Configuration of the CLASSD Non-Overlapping value. - */ - uint32_t novrval; - /** - * @brief Configuration of the CLASSD left channel attenuation. - */ - uint32_t attl; - /** - * @brief Configuration of the CLASSD right channel attenuation. - */ - uint32_t attr; - /** - * @brief Configuration of the CLASSD de-emphasis filter. - */ - uint32_t deemp; - /** - * @brief Configuration of the CLASSD swap left right channel. - */ - uint32_t swap; - /** - * @brief Configuration of the CLASSD sample frequency. - */ - uint32_t frame; - /** - * @brief Configuration of the CLASSD EQ config. - */ - uint32_t eqcfg; - /** - * @brief Configuration of the CLASSD mono signal. - */ - uint32_t mono; - /** - * @brief Configuration of the CLASSD mono mode. - */ - uint32_t mono_mode; -} CLASSDConfig; - -/** - * @brief Structure representing an CLASSD driver. - */ -struct CLASSDDriver { - /** - * @brief Driver state. - */ - classdstate_t state; - /** - * @brief Current configuration data. - */ - const CLASSDConfig *config; - /** - * @brief Pointer to the WDT registers block. - */ - Classd *classd; - /** - * @brief Transmit DMA stream. - */ - sama_dma_channel_t *dmatx; - /** - * @brief TX DMA mode bit mask. - */ - uint32_t txdmamode; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ -extern CLASSDDriver CLASSDD0; - -#ifdef __cplusplus -extern "C" { -#endif - void classdInit(void); - void classdObjectInit(CLASSDDriver *classdp); - void classdStart(CLASSDDriver *classdp, const CLASSDConfig *config); - void classdStop(CLASSDDriver *classdp); - void classdSetSampleFrame(CLASSDConfig *classdconfigp, uint8_t *music_file); - void classdSendAudioI(CLASSDDriver *classdp, const void *txbuf); - void classdSendAudio(CLASSDDriver *classdp, const void *txbuf); - void classdMuteChannel(CLASSDDriver *classdp, bool left, bool right); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_USE_CLASSD */ - -#endif /* SAMA_CLASSD_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.c b/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.c deleted file mode 100644 index 761c5b66b..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.c +++ /dev/null @@ -1,955 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_lcdc.c - * @brief SAMA LCDC support code. - * - * @addtogroup SAMA5D2x_LCDC - * @{ - */ - -#include "hal.h" - -#if (SAMA_USE_LCDC) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -/* - * @brief NO CACHE attribute - */ -#if !defined(NO_CACHE) -#define NO_CACHE __attribute__((section (".nocache"))) -#endif -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ -/* - * @name Configuration Macros - * @{ - */ -/* - * @brief Transfer Descriptor Fetch Enable - */ -#define LCDC_CTRL_DFETCH (0x1u << 0) -/* - * @brief Channel Enable Register - */ -#define LCDC_CHER_CHEN (0x1u << 0) -/* - * @brief Channel Disable Register - */ -#define LCDC_CHDR_CHDIS (0x1u << 0) -/* - * @brief Update Overlay Attributes Enable Register - */ -#define LCDC_CHER_UPDATEEN (0x1u << 1) -/* - * @brief Blender DMA Layer Enable - */ -#define LCDC_CFG_DMA (0x1u << 8) -/* - * @brief Blender Overlay Layer Enable - */ -#define LCDC_CFG_OVR (0x1u << 7) -/* - * @brief Pixel Stride - */ -#define LCDC_CFG_PSTRIDE_Pos 0 -#define LCDC_CFG_PSTRIDE_Msk (0xffffffffu << LCDC_CFG_PSTRIDE_Pos) -#define LCDC_CFG_PSTRIDE(value) ((LCDC_CFG_PSTRIDE_Msk & ((value) << \ - LCDC_CFG_PSTRIDE_Pos))) -/* - * @brief Horizontal Stride - */ -#define LCDC_CFG_XSTRIDE_Pos 0 -#define LCDC_CFG_XSTRIDE_Msk (0xffffffffu << LCDC_CFG_XSTRIDE_Pos) -#define LCDC_CFG_XSTRIDE(value) ((LCDC_CFG_XSTRIDE_Msk & ((value) << \ - LCDC_CFG_XSTRIDE_Pos))) -/* - * @brief Hardware Rotation Optimization Disable - */ -#define LCDC_CFG_ROTDIS (0x1u << 12) - -/* - * @brief Horizontal Window Position - */ -#define LCDC_CFG_XPOS_Pos 0 -#define LCDC_CFG_XPOS_Msk (0x7ffu << LCDC_CFG_XPOS_Pos) -#define LCDC_CFG_XPOS(value) ((LCDC_CFG_XPOS_Msk & ((value) << LCDC_CFG_XPOS_Pos))) - -/* - * @brief Vertical Window Position - */ -#define LCDC_CFG_YPOS_Pos 16 -#define LCDC_CFG_YPOS_Msk (0x7ffu << LCDC_CFG_YPOS_Pos) -#define LCDC_CFG_YPOS(value) ((LCDC_CFG_YPOS_Msk & ((value) << LCDC_CFG_YPOS_Pos))) - -/* - * @brief Horizontal Window Size - */ -#define LCDC_CFG_XSIZE_Pos 0 -#define LCDC_CFG_XSIZE_Msk (0x7ffu << LCDC_CFG_XSIZE_Pos) -#define LCDC_CFG_XSIZE(value) ((LCDC_CFG_XSIZE_Msk & ((value) << LCDC_CFG_XSIZE_Pos))) - -/* - * @brief Vertical Window Size - */ -#define LCDC_CFG_YSIZE_Pos 16 -#define LCDC_CFG_YSIZE_Msk (0x7ffu << LCDC_CFG_YSIZE_Pos) -#define LCDC_CFG_YSIZE(value) ((LCDC_CFG_YSIZE_Msk & ((value) << LCDC_CFG_YSIZE_Pos))) - -/* - * @brief Horizontal image Size in Memory - */ -#define LCDC_CFG_XMEMSIZE_Pos 0 -#define LCDC_CFG_XMEMSIZE_Msk (0x7ffu << LCDC_CFG_XMEMSIZE_Pos) -#define LCDC_CFG_XMEMSIZE(value) ((LCDC_CFG_XMEMSIZE_Msk & ((value) << LCDC_CFG_XMEMSIZE_Pos))) - -/* - * @brief Vertical image Size in Memory - */ -#define LCDC_CFG_YMEMSIZE_Pos 16 -#define LCDC_CFG_YMEMSIZE_Msk (0x7ffu << LCDC_CFG_YMEMSIZE_Pos) -#define LCDC_CFG_YMEMSIZE(value) ((LCDC_CFG_YMEMSIZE_Msk & ((value) << LCDC_CFG_YMEMSIZE_Pos))) - -/** @} */ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -LCDCDriver LCDCD0; - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ -/** - * @brief DMA Channel Descriptor. - */ -typedef struct { - /** - * @brief Frame Buffer base address register. - */ - uint32_t addr; - /** - * @brief Transfer Control register. - */ - uint32_t ctrl; - /** - * @brief Next Descriptor Address register. - */ - uint32_t next; -} lcdc_dma_descriptor_t; - -/* Variable layer data */ -typedef struct { - lcdc_dma_descriptor_t *dma_desc; - lcdc_dma_descriptor_t *dma_u_desc; - lcdc_dma_descriptor_t *dma_v_desc; - void *buffer; - uint8_t bpp; - uint8_t num_colors; -} layerdata_t; - -/* - * @brief Hardware info about the layers - */ -typedef struct { - layerdata_t *data; - bool stride_supported; - /* regs: _ER, _DR, _SR, _IER, _IDR, _IMR, _ISR */ - volatile uint32_t *reg_enable; - /* regs: blender */ - volatile uint32_t *reg_blender; - /* _HEAD, _ADDRESS, _CONTROL, _NEXT */ - volatile uint32_t *reg_dma_head; - /* _HEAD, _ADDRESS, _CONTROL, _NEXT */ - volatile uint32_t *reg_dma_u_head; - /* _HEAD, _ADDRESS, _CONTROL, _NEXT */ - volatile uint32_t *reg_dma_v_head; - /* regs: _CFG0, _CFG1 (RGB mode...) */ - volatile uint32_t *reg_cfg; - /* X Y register, W H register */ - volatile uint32_t *reg_win; - /* regs: stride */ - volatile uint32_t *reg_stride; - /* regs: RGB Default, RGB Key, RGB Mask */ - volatile uint32_t *reg_color; - /* regs: scale */ - volatile uint32_t *reg_scale; - /* regs: CLUT */ - volatile uint32_t *reg_clut; -} layerinfo_t; - -/* Base Layer */ -static layerdata_t lcdd_base; -/* OVR1 Layer */ -static layerdata_t lcdd_ovr1; -/* OVR2 Layer */ -static layerdata_t lcdd_ovr2; -/* HEO Layer */ -static layerdata_t lcdd_heo; -/* HCC Layer */ -static layerdata_t lcdd_hcc; - -/* - * @brief DMA descriptor - * @note The DMA Channel Descriptor (DSCR) must be aligned on a 64-bit boundary. - */ -ALIGNED_VAR(8) -/* DMA descriptor for Base Layer */ -NO_CACHE static lcdc_dma_descriptor_t base_dma_desc; - -ALIGNED_VAR(8) -/* DMA descriptor for OVR1 Layer */ -NO_CACHE static lcdc_dma_descriptor_t ovr1_dma_desc; - -ALIGNED_VAR(8) -/* DMA descriptor for OVR2 Layer */ -NO_CACHE static lcdc_dma_descriptor_t ovr2_dma_desc; - -ALIGNED_VAR(8) -/* DMA descriptor for HEO Layer */ -NO_CACHE static lcdc_dma_descriptor_t heo_dma_desc; -ALIGNED_VAR(8) -/* DMA descriptor for HEO U-UV Layer */ -NO_CACHE static lcdc_dma_descriptor_t heo_dma_u_desc; -ALIGNED_VAR(8) -/* DMA descriptor for HEO V Layer */ -NO_CACHE static lcdc_dma_descriptor_t heo_dma_v_desc; - -ALIGNED_VAR(8) -/* DMA descriptor for HCC Layer */ -NO_CACHE static lcdc_dma_descriptor_t hcc_dma_desc; - -/** - * @brief Information about layers - */ -static const layerinfo_t lcdd_layers[] = { - /* 0: LCDD_CONTROLLER */ - { - .stride_supported = false, - .reg_enable = &LCDC->LCDC_LCDEN, - }, - - /* 1: LCDD_BASE */ - { - .data = &lcdd_base, - .stride_supported = false, - .reg_enable = &LCDC->LCDC_BASECHER, - .reg_blender = &LCDC->LCDC_BASECFG4, - .reg_dma_head = &LCDC->LCDC_BASEHEAD, - .reg_cfg = &LCDC->LCDC_BASECFG0, - .reg_stride = &LCDC->LCDC_BASECFG2, - .reg_color = &LCDC->LCDC_BASECFG3, - .reg_clut = &LCDC->LCDC_BASECLUT[0] - }, - - /* 2: LCDD_OVR1 */ - { - .data = &lcdd_ovr1, - .stride_supported = true, - .reg_enable = &LCDC->LCDC_OVR1CHER, - .reg_blender = &LCDC->LCDC_OVR1CFG9, - .reg_dma_head = &LCDC->LCDC_OVR1HEAD, - .reg_cfg = &LCDC->LCDC_OVR1CFG0, - .reg_win = &LCDC->LCDC_OVR1CFG2, - .reg_stride = &LCDC->LCDC_OVR1CFG4, - .reg_color = &LCDC->LCDC_OVR1CFG6, - .reg_clut = &LCDC->LCDC_OVR1CLUT[0], - }, - - /* 3: LCDD_HEO */ - { - .data = &lcdd_heo, - .stride_supported = true, - .reg_enable = &LCDC->LCDC_HEOCHER, - .reg_blender = &LCDC->LCDC_HEOCFG12, - .reg_dma_head = &LCDC->LCDC_HEOHEAD, - .reg_dma_u_head = &LCDC->LCDC_HEOUHEAD, - .reg_dma_v_head = &LCDC->LCDC_HEOVHEAD, - .reg_cfg = &LCDC->LCDC_HEOCFG0, - .reg_win = &LCDC->LCDC_HEOCFG2, - .reg_stride = &LCDC->LCDC_HEOCFG5, - .reg_color = &LCDC->LCDC_HEOCFG9, - .reg_scale = &LCDC->LCDC_HEOCFG13, - .reg_clut = &LCDC->LCDC_HEOCLUT[0], - }, - - /* 4: LCDD_OVR2 */ - { - .data = &lcdd_ovr2, - .stride_supported = true, - .reg_enable = &LCDC->LCDC_OVR2CHER, - .reg_blender = &LCDC->LCDC_OVR2CFG9, - .reg_dma_head = &LCDC->LCDC_OVR2HEAD, - .reg_cfg = &LCDC->LCDC_OVR2CFG0, - .reg_win = &LCDC->LCDC_OVR2CFG2, - .reg_stride = &LCDC->LCDC_OVR2CFG4, - .reg_color = &LCDC->LCDC_OVR2CFG6, - .reg_clut = &LCDC->LCDC_OVR2CLUT[0], - } - , - /* 5: N/A */ - { - .data = NULL, - }, - - /* 6: LCDD_CUR */ - { - .data = &lcdd_hcc, - .stride_supported = false, - }, -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/* - * @brief Clear DMA channel descriptor - * - * @param[in] descp pointer to lcdc_dma_descriptor - * @param[in] dma_regp pointer to LCDC leyer register - * - * @notapi - */ -static void clear_dma_desc(lcdc_dma_descriptor_t *descp, volatile uint32_t *dma_regp) { - /* Modify descriptor */ - if (descp) { - descp->ctrl &= ~LCDC_CTRL_DFETCH; - descp->next = (uint32_t)descp; - //cacheCleanRegion(descp, sizeof(lcdc_dma_descriptor_t)); - } - - /* Modify registers */ - dma_regp[2] &= ~LCDC_CTRL_DFETCH; - dma_regp[3] = (uint32_t)descp; -} - -/** - * @brief Computing scaling factor. - * - * @param[in] layerp pointer to a layerinfo_t struct - * @param[out] xfactorp pointer to xfactor scaling factor - * @param[out] yfactorp pointer to yfactor scaling factor - * - * @notapi - */ -static void compute_scaling_factors(const layerinfo_t *layerp, - uint16_t* xfactorp, uint16_t* yfactorp) -{ - uint16_t xmemsize, ymemsize; - uint16_t xsize, ysize; - -#ifdef LCDC_HEOCFG41_XPHIDEF - uint16_t xfactor_1st, yfactor_1st; -#endif - - xmemsize = (layerp->reg_win[2] & LCDC_CFG_XMEMSIZE_Msk) >> LCDC_CFG_XMEMSIZE_Pos; - ymemsize = (layerp->reg_win[2] & LCDC_CFG_YMEMSIZE_Msk) >> LCDC_CFG_YMEMSIZE_Pos; - xsize = (layerp->reg_win[1] & LCDC_CFG_XSIZE_Msk) >> LCDC_CFG_XSIZE_Pos; - ysize = (layerp->reg_win[1] & LCDC_CFG_YSIZE_Msk) >> LCDC_CFG_YSIZE_Pos; - -#ifdef LCDC_HEOCFG41_XPHIDEF - /* we assume that XPHIDEF & YPHIDEF are 0 */ - xfactor_1st = (2048 * xmemsize / xsize) + 1; - yfactor_1st = (2048 * ymemsize / ysize) + 1; - - if ((xfactor_1st * xsize / 2048) > xmemsize) - *xfactorp = xfactor_1st - 1; - else - *xfactorp = xfactor_1st; - - if ((yfactor_1st * ysize / 2048) > ymemsize) - *yfactorp = yfactor_1st - 1; - else - *yfactorp = yfactor_1st; -#else - *xfactorp = 1024 * (xmemsize + 1) / (xsize + 1); - *yfactorp = 1024 * (ymemsize + 1) / (ysize + 1); -#endif -} - -/** - * @brief Configures LCDC layers according to configuration struct. - * - * @param[in] listp pointer to a LCDCLayerConfig array - * @param[in] length length of array - * - * @notapi - */ -void layer_config(LCDCLayerConfig *listp, size_t length) { - uint8_t i; - uint8_t bpp_bit; - uint8_t bpp; - uint32_t index; - - uint32_t padding = 0; - uint32_t src_w, src_h, img_w, img_h; - uint32_t bits_per_row, bytes_per_row; - - LCDCLayerConfig *layerp; - - for (i = 0; i < length; i++) { - index = listp[i].layer_id; - - osalDbgAssert((index != LCDD_CONTROLLER) || (index != LCDD_CUR), "This is not a real layer"); - - layerp = &listp[i]; - uint16_t w, h, x, y; - - bpp = layerp->bpp; - w = layerp->width; - h = layerp->height; - x = layerp->x_pos; - y = layerp->y_pos; - img_w = layerp->w_img; - img_h = layerp->h_img; - - /* Bpp settings */ - lcdd_layers[index].reg_cfg[1] = layerp->bpp; - bpp = bpp >> 4; - - if (bpp == 1 || bpp < 5) { - bpp_bit = 16; - } - else if (bpp == 5 || bpp == 6) { - bpp_bit = 18; - } - else if (bpp == 7 || bpp == 8) { - bpp_bit = 19; - } - else if (bpp == 9 || bpp == 10) { - bpp_bit = 24; - } - else if (bpp == 11) { - bpp_bit = 25; - } - else if (bpp == 12 || bpp == 13) { - bpp_bit = 32; - } - else { - bpp_bit = 12; - } - - /* Set display buffer & mode */ - bits_per_row = img_w * bpp_bit; - bytes_per_row = bits_per_row >> 3; - - if (bits_per_row & 0x7) { - bytes_per_row++; - } - if (bytes_per_row & 0x3) { - padding = 4 - (bytes_per_row & 0x3); - } - /* No rotation optimization */ - lcdd_layers[index].reg_cfg[0] |= LCDC_CFG_ROTDIS; - - /* Configure PSTRIDE if supported */ - if (lcdd_layers[index].stride_supported) - lcdd_layers[index].reg_stride[1] = LCDC_CFG_PSTRIDE(0); - /* Configure XSTRIDE if supported */ - lcdd_layers[index].reg_stride[0] = LCDC_CFG_XSTRIDE(padding); - - /* Set window & position */ - if (lcdd_layers[index].reg_win) { - - /* Re - calculate to eliminate hardware overflow */ - if (x + w > LCDCD0.config->width) { - w = LCDCD0.config->width - x; - } - if (y + h > LCDCD0.config->height) { - h = LCDCD0.config->height - y; - } - - if (w == 0) - w++; - - if (h == 0) - h++; - - lcdd_layers[index].reg_win[0] = LCDC_CFG_XPOS(x) | LCDC_CFG_YPOS(y); - lcdd_layers[index].reg_win[1] = LCDC_CFG_XSIZE(w - 1) | LCDC_CFG_YSIZE(h - 1); - } - - /* Scaling setup, only HEO layer has scaling register */ - if (lcdd_layers[index].reg_win && lcdd_layers[index].reg_scale) { - src_w = img_w; - src_h = img_h; - - lcdd_layers[index].reg_win[2] = LCDC_CFG_XMEMSIZE(src_w - 1) | - LCDC_CFG_YMEMSIZE(src_h - 1); - /* Scaled */ - if (w != src_w || h != src_h) { - uint16_t scale_w, scale_h; - compute_scaling_factors(&lcdd_layers[index], &scale_w, &scale_h); - lcdd_layers[index].reg_scale[0] = LCDC_HEOCFG13_YFACTOR(scale_h) | - LCDC_HEOCFG13_XFACTOR(scale_w) | - LCDC_HEOCFG13_SCALEN; - } - /* Disable scaling */ - else { - lcdd_layers[index].reg_scale[0] = 0; - } - } - - /* Configure Descriptor */ - lcdd_layers[index].data->dma_desc->addr = (uint32_t)layerp->buffer; - lcdd_layers[index].data->dma_desc->ctrl = LCDC_CTRL_DFETCH; - lcdd_layers[index].data->dma_desc->next = (uint32_t)lcdd_layers[index].data->dma_desc; - - lcdd_layers[index].reg_dma_head[1] = (uint32_t)lcdd_layers[index].data->dma_desc->addr; - lcdd_layers[index].reg_dma_head[2] = LCDC_CTRL_DFETCH; - lcdd_layers[index].reg_dma_head[3] = (uint32_t)lcdd_layers[index].data->dma_desc; - - /* Configure layer */ - lcdd_layers[index].reg_enable[0] = LCDC_CHER_UPDATEEN; - lcdd_layers[index].reg_blender[0] |= LCDC_CFG_DMA | LCDC_CFG_OVR; - } -} - -/** - * @brief Enable Display. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - */ -static void lcdc_on(LCDCDriver *lcdcp) { - - uint32_t pixel_clock = lcdcp->config->framerate; - pixel_clock *= lcdcp->config->timing_hpw + lcdcp->config->timing_hbp + - lcdcp->config->width + lcdcp->config->timing_hfp; - pixel_clock *= lcdcp->config->timing_vpw + lcdcp->config->timing_vbp + - lcdcp->config->height + lcdcp->config->timing_vfp; - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - /* Configure LCD timing parameters, signal polarity and clock period. */ - if( LCDC->LCDC_LCDCFG0 & LCDC_LCDCFG0_CLKSEL) { - LCDC->LCDC_LCDCFG0 = LCDC_LCDCFG0_CLKDIV((SAMA_MCK * 2) / pixel_clock - 2) | - LCDC_LCDCFG0_CGDISHEO | LCDC_LCDCFG0_CGDISOVR1 | - LCDC_LCDCFG0_CGDISOVR2 | LCDC_LCDCFG0_CGDISBASE | - LCDC_LCDCFG0_CLKPWMSEL | LCDC_LCDCFG0_CLKSEL; - } - else { - LCDC->LCDC_LCDCFG0 = LCDC_LCDCFG0_CLKDIV(SAMA_MCK / pixel_clock - 2) | - LCDC_LCDCFG0_CGDISBASE | LCDC_LCDCFG0_CGDISHEO | - LCDC_LCDCFG0_CLKPWMSEL; - } - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - LCDC->LCDC_LCDCFG1 = LCDC_LCDCFG1_VSPW(lcdcp->config->timing_vpw - 1) | - LCDC_LCDCFG1_HSPW(lcdcp->config->timing_hpw - 1); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - LCDC->LCDC_LCDCFG2 = LCDC_LCDCFG2_VBPW(lcdcp->config->timing_vbp) | - LCDC_LCDCFG2_VFPW(lcdcp->config->timing_vfp - 1); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - LCDC->LCDC_LCDCFG3 = LCDC_LCDCFG3_HBPW(lcdcp->config->timing_hbp - 1) | - LCDC_LCDCFG3_HFPW(lcdcp->config->timing_hfp - 1); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - LCDC->LCDC_LCDCFG4 = LCDC_LCDCFG4_RPF(lcdcp->config->height - 1) | - LCDC_LCDCFG4_PPL(lcdcp->config->width - 1); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - LCDC->LCDC_LCDCFG5 = LCDC_LCDCFG5_GUARDTIME(30) | LCDC_LCDCFG5_MODE_OUTPUT_24BPP | - LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS | LCDC_LCDCFG5_VSPOL | - LCDC_LCDCFG5_HSPOL; - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - LCDC->LCDC_LCDCFG6 = LCDC_LCDCFG6_PWMCVAL(0xF0) | LCDC_LCDCFG6_PWMPOL | - LCDC_LCDCFG6_PWMPS(6); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - - /* Enable the Pixel Clock. */ - LCDC->LCDC_LCDEN = LCDC_LCDEN_CLKEN; - - /* Poll to check that clock is running. */ - while (!(LCDC->LCDC_LCDSR & LCDC_LCDSR_CLKSTS)); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - /* Enable Horizontal and Vertical Synchronization. */ - LCDC->LCDC_LCDEN = LCDC_LCDEN_SYNCEN; - /* Poll to check that the synchronization is up. */ - while (!(LCDC->LCDC_LCDSR & LCDC_LCDSR_LCDSTS)); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - /* Enable the display power signal. */ - LCDC->LCDC_LCDEN = LCDC_LCDEN_DISPEN; - /* Poll to check that the power signal is activated. */ - while (!(LCDC->LCDC_LCDSR & LCDC_LCDSR_DISPSTS)); - - /* Wait for clock domain synchronization to be complete. */ - while ((LCDC->LCDC_LCDSR & LCDC_LCDSR_SIPSTS)); - - /* Enable backlight */ - LCDC->LCDC_LCDEN = LCDC_LCDEN_PWMEN; -} - -/** - * @brief Disable Display. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - */ -static void lcdc_off(void) { - - /* Disable all DMA channel descriptors */ - clear_dma_desc(&base_dma_desc, &LCDC->LCDC_BASEADDR); - clear_dma_desc(&ovr1_dma_desc, &LCDC->LCDC_OVR1ADDR); - clear_dma_desc(&ovr2_dma_desc, &LCDC->LCDC_OVR2ADDR); - clear_dma_desc(&heo_dma_desc, &LCDC->LCDC_HEOADDR); - clear_dma_desc(&heo_dma_u_desc, &LCDC->LCDC_HEOUADDR); - clear_dma_desc(&heo_dma_v_desc, &LCDC->LCDC_HEOVADDR); - - /* Disable DMA channels */ - LCDC->LCDC_BASECHDR = LCDC_BASECHDR_CHDIS; - LCDC->LCDC_OVR1CHDR = LCDC_OVR1CHDR_CHDIS; - LCDC->LCDC_OVR2CHDR = LCDC_OVR2CHDR_CHDIS; - LCDC->LCDC_HEOCHDR = LCDC_HEOCHDR_CHDIS; - LCDC->LCDC_BASECFG4 = 0; - - /* Poll CHSR until the channel is successfully disabled. */ - while (LCDC->LCDC_BASECHSR & LCDC_BASECHSR_CHSR); - while (LCDC->LCDC_OVR1CHSR & LCDC_OVR1CHSR_CHSR); - while (LCDC->LCDC_OVR2CHSR & LCDC_OVR1CHSR_CHSR); - while (LCDC->LCDC_HEOCHSR & LCDC_HEOCHSR_CHSR); - - /* Disable backlight */ - LCDC->LCDC_LCDDIS = LCDC_LCDDIS_PWMDIS; - /* Poll PWMSTS: field of the LCDC_LCDSR register to verify that the PWM - is no activated. */ - while (LCDC->LCDC_LCDSR & LCDC_LCDSR_PWMSTS); - - /* Disable the DISP signal. */ - LCDC->LCDC_LCDDIS = LCDC_LCDDIS_DISPDIS; - /* Poll DISPSTS field of the LCDC_LCDSR register to verify that the DISP - is no longer activated. */ - while (LCDC->LCDC_LCDSR & LCDC_LCDSR_DISPSTS); - - /* Disable the hsync and vsync signals. */ - LCDC->LCDC_LCDDIS = LCDC_LCDDIS_SYNCDIS; - /* Poll LCDSTS field of the LCDC_LCDSR register to check that the - synchronization is off. */ - while (LCDC->LCDC_LCDSR & LCDC_LCDSR_LCDSTS); - - /* Disable the Pixel clock. */ - LCDC->LCDC_LCDDIS = LCDC_LCDDIS_CLKDIS; - /* Poll CLKSTS field of the LCDC_LCDSR register to check that Pixel Clock - is disabled. */ - while (LCDC->LCDC_LCDSR & LCDC_LCDSR_CLKSTS); -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level LCDC driver initialization. - * - * @notapi - */ -void lcdc_lld_init(void) { -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX0, ID_LCDC, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - - /* Driver initialization.*/ - lcdcObjectInit(&LCDCD0); - LCDCD0.lcdc = LCDC; - - /* Reset layer information */ - lcdd_base.bpp = 0; - lcdd_base.buffer = NULL; - lcdd_base.dma_desc = &base_dma_desc; - - lcdd_ovr1.bpp = 0; - lcdd_ovr1.buffer = NULL; - lcdd_ovr1.dma_desc = &ovr1_dma_desc; - - lcdd_ovr2.bpp = 0; - lcdd_ovr2.buffer = NULL; - lcdd_ovr2.dma_desc = &ovr2_dma_desc; - - lcdd_heo.bpp = 0; - lcdd_heo.buffer = NULL; - lcdd_heo.dma_desc = &heo_dma_desc; - lcdd_heo.dma_u_desc = &heo_dma_u_desc; - lcdd_heo.dma_v_desc = &heo_dma_v_desc; - - lcdd_hcc.bpp = 0; - lcdd_base.buffer = NULL; - lcdd_hcc.dma_desc = &hcc_dma_desc; - - /* Disable LCD controller */ - lcdc_off(); - - /* Timing Engine Configuration */ - - /* Disable interrupt */ - LCDC->LCDC_LCDIDR = 0xFFFFFFFF; - - /* Base */ - LCDC->LCDC_BASECFG0 = LCDC_BASECFG0_DLBO | LCDC_BASECFG0_BLEN_AHB_INCR16; - - /* Overlay 1, GA 0xFF */ - LCDC->LCDC_OVR1CFG0 = LCDC_OVR1CFG0_DLBO | LCDC_OVR1CFG0_BLEN_AHB_BLEN_INCR16 | - LCDC_OVR1CFG0_ROTDIS; - - LCDC->LCDC_OVR1CFG9 = LCDC_OVR1CFG9_GA(0xFF) | LCDC_OVR1CFG9_GAEN; - - /* Overlay 2, GA 0xFF */ - LCDC->LCDC_OVR2CFG0 = LCDC_OVR2CFG0_DLBO | LCDC_OVR2CFG0_BLEN_AHB_INCR16 | - LCDC_OVR2CFG0_ROTDIS; - LCDC->LCDC_OVR2CFG9 = LCDC_OVR2CFG9_GA(0xFF) | LCDC_OVR2CFG9_GAEN; - - /* High End Overlay, GA 0xFF */ - LCDC->LCDC_HEOCFG0 = LCDC_HEOCFG0_DLBO | LCDC_HEOCFG0_BLEN_AHB_BLEN_INCR16 | - LCDC_HEOCFG0_ROTDIS; - LCDC->LCDC_HEOCFG12 = LCDC_HEOCFG12_GA(0xFF) | LCDC_HEOCFG12_GAEN; - LCDC->LCDC_HEOCFG14 = LCDC_HEOCFG14_CSCRY(0x94) | LCDC_HEOCFG14_CSCRU(0xCC) | - LCDC_HEOCFG14_CSCRV(0) | LCDC_HEOCFG14_CSCYOFF; - LCDC->LCDC_HEOCFG15 = LCDC_HEOCFG15_CSCGY(0x94) | LCDC_HEOCFG15_CSCGU(0x387) | - LCDC_HEOCFG15_CSCGV(0x3CD) | LCDC_HEOCFG15_CSCUOFF; - LCDC->LCDC_HEOCFG16 = LCDC_HEOCFG16_CSCBY(0x94)| LCDC_HEOCFG16_CSCBU(0) | - LCDC_HEOCFG16_CSCBV(0x102) | LCDC_HEOCFG16_CSCVOFF; -} - -/** - * @brief Configures and activates the LCDC peripheral. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @notapi - */ -void lcdc_lld_start(LCDCDriver *lcdcp) { - - /* Enable the LCDC peripheral clock. */ - pmcEnableLCDC(); - - /* Configure overlays */ - layer_config(lcdcp->config->listp, lcdcp->config->length); - -} - -/** - * @brief Deactivates the LCDC peripheral. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @notapi - */ -void lcdc_lld_stop(LCDCDriver *lcdcp) { - - if (lcdcp->state == LCDC_READY) { - - /* Disable display. */ - lcdc_off(); - - /* Disable the LCDC clock. */ - pmcDisableLCDC(); - } -} - -/** - * - * @brief Initializes the standard part of a @p LCDCDriver structure. - * - * @param[out] lcdcp pointer to a @p LCDCDriver object - * - * @init - */ -void lcdcObjectInit(LCDCDriver *lcdcp) { - lcdcp->state = LCDC_STOP; - lcdcp->config = NULL; -} - -/** - * @brief LCDC driver initialization. - * - * @notapi - */ -void lcdcInit(void) { - - lcdc_lld_init(); -} - -/** - * @brief Configures and activates the LCDC peripheral. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * @param[in] configp pointer to the LCDCConfig struct - * - * @api - */ -void lcdcStart(LCDCDriver *lcdcp, const LCDCConfig *configp) { - - osalDbgCheck(lcdcp != NULL); - - osalSysLock(); - osalDbgAssert((lcdcp->state == LCDC_STOP) , "invalid state"); - lcdcp->config = configp; - lcdc_lld_start(lcdcp); - lcdcp->state = LCDC_READY; - osalSysUnlock(); - - /* Enable display. */ - lcdc_on(lcdcp); -} - -/** - * @brief Deactivates the LCDC peripheral. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @api - */ -void lcdcStop(LCDCDriver *lcdcp) { - - osalDbgCheck(lcdcp != NULL); - - osalSysLock(); - osalDbgAssert((lcdcp->state == LCDC_READY), "invalid state"); - - lcdc_lld_stop(lcdcp); - lcdcp->state = LCDC_STOP; - osalSysUnlock(); -} - -void lcdcShowLayer(LCDCDriver *lcdcp, uint8_t id, bool enable) { - (void)lcdcp; - - if(enable) { - lcdd_layers[id].reg_enable[0] = LCDC_CHER_CHEN; - } - else { - lcdd_layers[id].reg_enable[1] = LCDC_CHDR_CHDIS; - } -} - -/* - * @brief brief Set the backlight of the LCD. - * - * param[in] level Backlight brightness level [1..255], - * 255 means maximum brightness. - * - * @api - */ -void lcdcSetBacklight(uint32_t level) { - uint32_t cfg = LCDC->LCDC_LCDCFG6 & ~LCDC_LCDCFG6_PWMCVAL_Msk; - LCDC->LCDC_LCDCFG6 = cfg | LCDC_LCDCFG6_PWMCVAL(level); -} - -#if (TRUE == LCDC_USE_MUTUAL_EXCLUSION) - -/** - * @brief Gains exclusive access to the LCDC module. - * @details This function tries to gain ownership to the LCDC module, if the - * module is already being used then the invoking thread is queued. - * @pre In order to use this function the option - * @p LCDC_USE_MUTUAL_EXCLUSION must be enabled. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @sclass - */ -void lcdcAcquireBusS(LCDCDriver *lcdcp) { - - osalDbgCheckClassS(); - osalDbgCheck(lcdcp == &LCDCD0); - -#if (TRUE == CH_CFG_USE_MUTEXES) - chMtxLockS(&lcdcp->lock); -#else - chSemWaitS(&lcdcp->lock); -#endif -} - -/** - * @brief Gains exclusive access to the LCDC module. - * @details This function tries to gain ownership to the LTDC module, if the - * module is already being used then the invoking thread is queued. - * @pre In order to use this function the option - * @p LCDC_USE_MUTUAL_EXCLUSION must be enabled. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @api - */ -void lcdcAcquireBus(LCDCDriver *lcdcp) { - - osalSysLock(); - lcdcAcquireBusS(lcdcp); - osalSysUnlock(); -} - -/** - * @brief Releases exclusive access to the LCDC module. - * @pre In order to use this function the option - * @p LCDC_USE_MUTUAL_EXCLUSION must be enabled. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @sclass - */ -void lcdcReleaseBusS(LCDCDriver *lcdcp) { - - osalDbgCheckClassS(); - osalDbgCheck(lcdcp == &LCDCD0); - -#if (TRUE == CH_CFG_USE_MUTEXES) - chMtxUnlockS(&lcdcp->lock); -#else - chSemSignalI(&lcdcp->lock); -#endif -} - -/** - * @brief Releases exclusive access to the LCDC module. - * @pre In order to use this function the option - * @p LCDC_USE_MUTUAL_EXCLUSION must be enabled. - * - * @param[in] lcdcp pointer to the @p LCDCDriver object - * - * @api - */ -void lcdcReleaseBus(LCDCDriver *lcdcp) { - - osalSysLock(); - lcdcReleaseBusS(lcdcp); - osalSysUnlock(); -} - -#endif /* LCDC_USE_MUTUAL_EXCLUSION */ - -#endif /* SAMA_USE_LCDC == TRUE */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.h b/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.h deleted file mode 100644 index 4a9237024..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_lcdc.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_lcdc.h - * @brief SAMA LCDC support macros and structures. - * - * @addtogroup SAMA5D2x_LCDC - * @{ - */ - -#ifndef SAMA_LCDC_LLD_H -#define SAMA_LCDC_LLD_H - -/** - * @brief Using the LCDC driver. - */ -#if !defined(SAMA_USE_LCDC) || defined(__DOXYGEN__) -#define SAMA_USE_LCDC FALSE -#endif - -#if (SAMA_USE_LCDC) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name LCDC ID LAYERS - * @{ - */ -/* LCD controller ID, no display, configuration ONLY */ -#define LCDD_CONTROLLER 0 - -/* LCD base layer, display fixed size image */ -#define LCDD_BASE 1 - -/* LCD Overlay 1 */ -#define LCDD_OVR1 2 - -/* LCD Overlay 2 */ -#define LCDD_OVR2 4 - -/* LCD HighEndOverlay, support resize */ -#define LCDD_HEO 3 - -/* LCD Cursor, max size 128x128 */ -#define LCDD_CUR 6 -/** @} */ - -/** - * @name BPP MODE - * @{ - */ -#define LCDC_CFG_RGBMODE_12BPP_RGB_444 (0x0u << 4) -#define LCDC_CFG_RGBMODE_16BPP_ARGB_4444 (0x1u << 4) -#define LCDC_CFG_RGBMODE_16BPP_RGBA_4444 (0x2u << 4) -#define LCDC_CFG_RGBMODE_16BPP_RGB_565 (0x3u << 4) -#define LCDC_CFG_RGBMODE_16BPP_TRGB_1555 (0x4u << 4) -#define LCDC_CFG_RGBMODE_18BPP_RGB_666 (0x5u << 4) -#define LCDC_CFG_RGBMODE_18BPP_RGB_666PACKED (0x6u << 4) -#define LCDC_CFG_RGBMODE_19BPP_TRGB_1666 (0x7u << 4) -#define LCDC_CFG_RGBMODE_19BPP_TRGB_PACKED (0x8u << 4) -#define LCDC_CFG_RGBMODE_24BPP_RGB_888 (0x9u << 4) -#define LCDC_CFG_RGBMODE_24BPP_RGB_888_PACKED (0xAu << 4) -#define LCDC_CFG_RGBMODE_25BPP_TRGB_1888 (0xBu << 4) -#define LCDC_CFG_RGBMODE_32BPP_ARGB_8888 (0xCu << 4) -#define LCDC_CFG_RGBMODE_32BPP_RGBA_8888 (0xDu << 4) -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ -/** - * @brief LCDC_USE_WAIT. - */ -#if !defined(LCDC_USE_WAIT) || defined(__DOXYGEN__) -#define LCDC_USE_WAIT FALSE -#endif - -/** - * @brief LCDC_USE_MUTUAL_EXCLUSION. - */ -#if !defined(LCDC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define LCDC_USE_MUTUAL_EXCLUSION FALSE -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Driver state machine possible states. - */ -typedef enum { - LCDC_UNINIT = 0, /**< Not initialized.*/ - LCDC_STOP = 1, /**< Stopped.*/ - LCDC_READY = 2, /**< Ready.*/ - LCDC_ACTIVE = 3, /**< Executing commands.*/ -} lcdcstate_t; - -/** - * @brief Type of a structure representing an LCDC driver. - */ -typedef struct LCDCDriver LCDCDriver; - -/** - * @brief LCD display layer information. - */ -typedef struct { - /** - * @brief Display image buffer. - */ - void *buffer; - /** - * @brief Display image width. - */ - uint16_t width; - /** - * @brief Display image height. - */ - uint16_t height; - /** - * @brief Display image x position. - */ - uint16_t x_pos; - /** - * @brief Display image y_pos. - */ - uint16_t y_pos; - /** - * @brief Horizontal image Size in Memory. - */ - uint16_t w_img; - /** - * @brief Vertical image Size in Memory. - */ - uint16_t h_img; - /** - * @brief BPP mode. - */ - uint8_t bpp; - /** - * @brief Layer ID. - */ - uint8_t layer_id; -} LCDCLayerConfig; - -/** - * @brief Driver LCD configuration structure. - */ -typedef struct { - /** - * @brief Display image width. - */ - uint16_t width; - /** - * @brief Display image height. - */ - uint16_t height; - /** - * @brief Frame rate in Hz. - */ - uint8_t framerate; - /** - * @brief Vertical front porch in number of lines. - */ - uint8_t timing_vfp; - /** - * @brief Vertical back porch in number of lines. - */ - uint8_t timing_vbp; - /** - * @brief Vertical pulse width in number of lines. - */ - uint8_t timing_vpw; - /** - * @brief Horizontal front porch in LCDDOTCLK cycles. - */ - uint8_t timing_hfp; - /** - * @brief Horizontal back porch in LCDDOTCLK cycles. - */ - uint8_t timing_hbp; - /** - * @brief Horizontal pulse width in LCDDOTCLK cycles. - */ - uint8_t timing_hpw; - /** - * @brief lenght of LCDCLayerConfig array - * @note Number of layers to configure - */ - size_t length; - /** - * @brief pointer to LCDCLayerConfig array - */ - LCDCLayerConfig *listp; -} LCDCConfig; - -/** - * @brief Structure representing an LCDC driver. - */ -struct LCDCDriver { - /** - * @brief Driver state. - */ - lcdcstate_t state; - /** - * @brief Current configuration lcd data. - */ - const LCDCConfig *config; - /** - * @brief Pointer to the LCDC registers block. - */ - Lcdc *lcdc; - /* Multithreading stuff.*/ -#if (LCDC_USE_WAIT == TRUE) || defined(__DOXYGEN__) - thread_t *thread; -#endif /* LCDC_USE_WAIT */ -#if (LCDC_USE_MUTUAL_EXCLUSION == TRUE) -#if (CH_CFG_USE_MUTEXES == TRUE) - mutex_t lock; -#elif (CH_CFG_USE_SEMAPHORES == TRUE) - semaphore_t lock; -#endif -#endif /* LCDC_USE_MUTUAL_EXCLUSION */ -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -extern LCDCDriver LCDCD0; - -#ifdef __cplusplus -extern "C" { -#endif - void lcdcObjectInit(LCDCDriver *lcdcp); - void lcdcInit(void); - void lcdcStart(LCDCDriver *lcdcp, const LCDCConfig *configp); - void lcdcStop(LCDCDriver *lcdcp); - void lcdcShowLayer(LCDCDriver *lcdcp, uint8_t id, bool enable); - void lcdcSetBacklight(uint32_t level); -#if (LCDC_USE_MUTUAL_EXCLUSION) - void lcdcAcquireBusS(LCDCDriver *lcdcp); - void lcdcAcquireBus(LCDCDriver *lcdcp); - void lcdcReleaseBusS(LCDCDriver *lcdcp); - void lcdcReleaseBus(LCDCDriver *lcdcp); -#endif /* LCDC_USE_MUTUAL_EXCLUSION */ - -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_USE_LCDC */ - -#endif /* SAMA_LCDC_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c b/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c deleted file mode 100644 index 61d0fa1c8..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_matrix.c - * @brief SAMA MATRIX support code. - * - * @addtogroup SAMA5D2x_MATRIX - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver constant */ -/*===========================================================================*/ -#define SCFG_OFFSET 0x40u - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ -#define MATRIX_SCFG(value) (MATRIX_SCFG0 + (value * 4u)) -#define MATRIX_SCFG_FIXED_DEFMSTR(value) MATRIX_SCFG0_FIXED_DEFMSTR(value) -#define MATRIX_SCFG_DEFMSTR_TYPE(value) MATRIX_SCFG0_DEFMSTR_TYPE(value) - -/** - * @brief Enable write protection on MATRIX registers block. - * - * @param[in] mtxp pointer to a MATRIX register block. - * - * @notapi - */ -#define mtxEnableWP(mtxp) { \ - mtxp->MATRIX_WPMR = MATRIX_WPMR_WPKEY_PASSWD | MATRIX_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on MATRIX registers block. - * - * @param[in] matxp pointer to a MATRIX register block. - * - * @notapi - */ -#define mtxDisableWP(mtxp) { \ - mtxp->MATRIX_WPMR = MATRIX_WPMR_WPKEY_PASSWD; \ -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ -/** - * @brief Configures peripheral security - * - * @param[in] mtxp pointer to a MATRIX register block. - * @param[in] id PERIPHERAL_ID. - * @param[in] mode SECURE_PER or NOT_SECURE_PER. - * - * @retval true Peripheral is not secured. - * @retval false Peripheral is secured. - * - */ -bool mtxConfigPeriphSecurity(Matrix *mtxp, uint32_t id, bool mode) { - - uint32_t mask; - mask = id & 0x1F; - - mtxDisableWP(mtxp); - if (mode) { - mtxp->MATRIX_SPSELR[id / 32] |= (MATRIX_SPSELR_NSECP0 << mask); - } - else { - mtxp->MATRIX_SPSELR[id / 32] &= ~(MATRIX_SPSELR_NSECP0 << mask); - } - mtxEnableWP(mtxp); - - return (MATRIX0->MATRIX_SPSELR[id / 32] & (MATRIX_SPSELR_NSECP0 << mask)) & - (MATRIX1->MATRIX_SPSELR[id / 32] & (MATRIX_SPSELR_NSECP0 << mask)); -} - -/** - * @brief Associates slave with a kind of master - * @note masterID is set only if type is fixed default master. - * Specifying the number of a master which is not connected - * to the selected slave is equivalent to clearing DEFMSTR_TYPE. - * - * @param[in] mtxp pointer to a MATRIX register block. - * @param[in] slaveID Slave MATRIX ID. - * @param[in] type Select from - * No default master, - * Last access master, - * Fixed default master. - * @param[in] masterID Master MATRIX ID. - */ -void mtxConfigDefaultMaster(Matrix *mtxp, uint8_t slaveID, - uint8_t type, uint8_t masterID) { - - mtxDisableWP(mtxp); - - volatile uint32_t *scfgAddress = (uint32_t *) ((uint32_t) mtxp + SCFG_OFFSET + (4u * slaveID)); - *scfgAddress = MATRIX_SCFG_DEFMSTR_TYPE(type); - - if (type == FIXED_DEFAULT_MASTER) { - *scfgAddress = MATRIX_SCFG_FIXED_DEFMSTR(masterID); - } - mtxEnableWP(mtxp); -} - -/** - * @brief Configures slave security region - * - * @param[in] mtxp pointer to a MATRIX register block. - * @param[in] slaveID Slave MATRIX ID. - * @param[in] selMask Securable area. - * @param[in] readMask Secure for read. - * @param[in] writeMask Secure for write. - */ -void mtxConfigSlaveSec(Matrix *mtxp, uint8_t slaveID, - uint8_t selMask, uint8_t readMask, - uint8_t writeMask) { - - mtxDisableWP(mtxp); - mtxp->MATRIX_SSR[slaveID] = selMask | (readMask << 8) | - (writeMask << 16); - mtxEnableWP(mtxp); -} - -/** - * @brief Configures split area of region - * - * @param[in] mtxp pointer to a MATRIX register block. - * @param[in] slaveID Slave MATRIX ID. - * @param[in] areaSize Split size area. - * @param[in] mask Region securable area. - */ -void mtxSetSlaveSplitAddr(Matrix *mtxp, uint8_t slaveID, - uint8_t areaSize, uint8_t mask) { - - mtxDisableWP(mtxp); - uint8_t i = mask, j = 0; - uint32_t value = 0; - uint32_t pmask = 0; - for (i = 1; (i <= mask) && (j < 32); i <<= 1, j += 4) { - if (i & mask) { - value |= areaSize << j; - pmask |= 0x0F << j; - } - } - mtxp->MATRIX_SASSR[slaveID] = (mtxp->MATRIX_SASSR[slaveID] & ~pmask) | value; - mtxEnableWP(mtxp); -} - -/** - * @brief Configures size area of region - * @note Not applicable to internal security type - * - * @param[in] mtxp pointer to a MATRIX register block. - * @param[in] slaveID Slave MATRIX ID. - * @param[in] areaSize Size of total area. - * @param[in] mask Region securable area. - */ -void mtxSetSlaveRegionSize(Matrix *mtxp, uint8_t slaveID, - uint8_t areaSize, uint8_t mask) { - - osalDbgCheck(slaveID != 0); - - mtxDisableWP(mtxp); - uint8_t i = mask, j = 0; - uint32_t value = 0; - uint32_t pmask = 0; - for (i = 1; (i <= mask) && (j < 32 ); i <<= 1, j += 4) { - if (i & mask) { - value |= areaSize << j; - pmask |= 0x0F << j; - } - } - mtxp->MATRIX_SRTSR[slaveID] = (mtxp->MATRIX_SRTSR[slaveID] & ~pmask) | value; - mtxEnableWP(mtxp); -} - -/** - * @brief Changes the mapping of the chip so that the remap area - * mirrors the internal ROM or the EBI CS0. - */ -void mtxRemapRom(void) { - - AXIMX->AXIMX_REMAP = 0; - - /* Invalidate I-Cache*/ - L1C_InvalidateICacheAll(); - - /* Invalidate Region */ - cacheInvalidateRegion((void*)0, IRAM_SIZE); -} - -/** - * @brief Changes the mapping of the chip so that the remap area - * mirrors the internal ROM or the EBI CS0. - */ -void mtxRemapRam(void) { - - AXIMX->AXIMX_REMAP = AXIMX_REMAP_REMAP0; - - /* Invalidate I-Cache*/ - L1C_InvalidateICacheAll(); - - /* Clean I-Region */ - cacheCleanRegion((void*)IRAM_ADDR, IRAM_SIZE); - /* Invalidate Region */ - cacheInvalidateRegion((void*)0, IRAM_SIZE); -} - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.h b/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.h deleted file mode 100644 index 5cf4ee29b..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.h +++ /dev/null @@ -1,341 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_matrix.h - * @brief SAMA MATRIX support macros and structures. - * - * @addtogroup SAMA5D2x_MATRIX - * @{ - */ - -#ifndef SAMA_MATRIX_H -#define SAMA_MATRIX_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ -/** - * @name SECURE MATRIX mode macros - * @{ - */ -/** - * @brief The low area of region is the securable one. - */ -#define LOWER_AREA_SECURABLE 0x0u - -/** - * @brief The upper area of region is the non-securable one. - */ -#define UPPER_AREA_SECURABLE 0x1u - -/** - * @brief Securable area is secured for reads. - */ -#define SECURE_READ 0x0u - -/** - * @brief Securable area is secured for writes. - */ -#define SECURE_WRITE 0x0u - -/** - * @brief Securable area is non-secured for reads. - */ -#define NOT_SECURE_READ 0x1u - -/** - * @brief Securable area is non-secured for writes. - */ -#define NOT_SECURE_WRITE 0x1u - -/** - * @brief Peripheral Securable as secure. - */ -#define SECURE_PER FALSE - -/** - * @brief Peripheral Securable as not-secure. - */ -#define NOT_SECURE_PER TRUE -/** @} */ - -/** - * @name MASTER TYPE MATRIX macros - * @{ - */ -/** - * @brief No Default Master. - */ -#define NO_DEFAULT_MASTER 0x0u - -/** - * @brief Last Default Master. - */ -#define LAST_DEFAULT_MASTER 0x1u - -/** - * @brief Fixed Default Master. - */ -#define FIXED_DEFAULT_MASTER 0x2u -/** @} */ - -/** - * @name REGION MATRIX MASK macros - * @{ - */ -/** - * @brief Region 0. - */ -#define REGION_0_MSK (0x1u << 0) - -/** - * @brief Region 1. - */ -#define REGION_1_MSK (0x1u << 1) - -/** - * @brief Region 2. - */ -#define REGION_2_MSK (0x1u << 2) - -/** - * @brief Region 3. - */ -#define REGION_3_MSK (0x1u << 3) - -/** - * @brief Region 4. - */ -#define REGION_4_MSK (0x1u << 4) - -/** - * @brief Region 5. - */ -#define REGION_5_MSK (0x1u << 5) - -/** - * @brief Region 6. - */ -#define REGION_6_MSK (0x1u << 6) - -/** - * @brief Region 7. - */ -#define REGION_7_MSK (0x1u << 7) -/** @} */ - -/** - * @name REGION MATRIX macros - * @{ - */ -/** - * @brief Region 0. - */ -#define REGION_0 0x0u - -/** - * @brief Region 1. - */ -#define REGION_1 0x1u - -/** - * @brief Region 2. - */ -#define REGION_2 0x2u - -/** - * @brief Region 3. - */ -#define REGION_3 0x3u - -/** - * @brief Region 4. - */ -#define REGION_4 0x4u - -/** - * @brief Region 5. - */ -#define REGION_5 0x5u - -/** - * @brief Region 6. - */ -#define REGION_6 0x6u - -/** - * @brief Region 7. - */ -#define REGION_7 0x7u -/** @} */ - -/** - * @name AREA SIZE MATRIX macros - * @{ - */ -/** - * @brief Area size 4 KB. - */ -#define MATRIX_AREA_SIZE_4K 0x0u - -/** - * @brief Area size 8 KB. - */ -#define MATRIX_AREA_SIZE_8K 0x1u - -/** - * @brief Area size 16 KB. - */ -#define MATRIX_AREA_SIZE_16K 0x2u - -/** - * @brief Area size 32 KB. - */ -#define MATRIX_AREA_SIZE_32K 0x3u - -/** - * @brief Area size 64 KB. - */ -#define MATRIX_AREA_SIZE_64K 0x4u - -/** - * @brief Area size 128 KB. - */ -#define MATRIX_AREA_SIZE_128K 0x5u - -/** - * @brief Area size 256 KB. - */ -#define MATRIX_AREA_SIZE_256K 0x6u - -/** - * @brief Area size 512 KB. - */ -#define MATRIX_AREA_SIZE_512K 0x7u - -/** - * @brief Area size 1 MB. - */ -#define MATRIX_AREA_SIZE_1M 0x8u - -/** - * @brief Area size 2 MB. - */ -#define MATRIX_AREA_SIZE_2M 0x9u - -/** - * @brief Area size 4 MB. - */ -#define MATRIX_AREA_SIZE_4M 0xAu - -/** - * @brief Area size 8 MB. - */ -#define MATRIX_AREA_SIZE_8M 0xBu - -/** - * @brief Area size 16 MB. - */ -#define MATRIX_AREA_SIZE_16M 0xCu - -/** - * @brief Area size 32 MB. - */ -#define MATRIX_AREA_SIZE_32M 0xDu - -/** - * @brief Area size 64 MB. - */ -#define MATRIX_AREA_SIZE_64M 0xEu - -/** - * @brief Area size 128 MB. - */ -#define MATRIX_AREA_SIZE_128M 0xFu -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @brief Configure LANSECH per Region. - * - * @param[in] region Region to configure. - * @param[in] lansech Securable mode. - * - * @api - */ -#define mtxRegionLansech(region, lansech) (lansech << region) - -/** - * @brief Configure RDNSECH per Region. - * - * @param[in] region Region to configure. - * @param[in] rdnsech Read securable mode. - * - * @api - */ -#define mtxRegionRdnsech(region, rdnsech) (rdnsech << region) - -/** - * @brief Configure WRNSECH per Region. - * - * @param[in] region Region to configure. - * @param[in] wrnsech Write securable mode. - * - * @api - */ -#define mtxRegionWrnsech(region, wrnsech) (wrnsech << region) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - bool mtxConfigPeriphSecurity(Matrix *mtxp, uint32_t id, bool mode); - void mtxConfigDefaultMaster(Matrix *mtxp, uint8_t slaveID, - uint8_t type, uint8_t masterID); - void mtxConfigSlaveSec(Matrix *mtxp, uint8_t slaveID, - uint8_t selMask, uint8_t readMask, - uint8_t writeMask); - void mtxSetSlaveSplitAddr(Matrix *mtxp, uint8_t slaveID, - uint8_t area, uint8_t mask); - void mtxSetSlaveRegionSize(Matrix *mtxp, uint8_t slaveID, - uint8_t areaSize, uint8_t mask); - void mtxRemapRom(void); - void mtxRemapRam(void); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_MATRIX_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.c b/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.c deleted file mode 100644 index 97c0477da..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_onewire.c - * @brief SAMA ONEWIRE support code. - * - * @addtogroup SAMA5D2x_ONEWIRE - * @{ - */ - -#include "hal.h" - -#if (SAMA_USE_ONEWIRE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -/** - * @name Delays in standard speed mode. - * @{ - */ -#define A US2RTC(SAMA_PCK, 6) -#define B US2RTC(SAMA_PCK, 64) -#define C US2RTC(SAMA_PCK, 60) -#define D US2RTC(SAMA_PCK, 10) -#define E US2RTC(SAMA_PCK, 9) -#define F US2RTC(SAMA_PCK, 55) -#define G US2RTC(SAMA_PCK, 0) -#define H US2RTC(SAMA_PCK, 480) -#define I US2RTC(SAMA_PCK, 70) -#define J US2RTC(SAMA_PCK, 410) -/** @} */ - -#if SAMA_HAL_IS_SECURE -#define PAD_INPUT_MODE PAL_SAMA_FUNC_GPIO | \ - PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_OPD_OPENDRAIN | \ - PAL_SAMA_PUEN_PULLUP | \ - PAL_MODE_SECURE - -#define PAD_OUTPUT_MODE PAL_SAMA_FUNC_GPIO | \ - PAL_SAMA_DIR_OUTPUT | \ - PAL_SAMA_OPD_OPENDRAIN | \ - PAL_SAMA_PUEN_PULLUP | \ - PAL_MODE_SECURE -#else -#define PAD_INPUT_MODE PAL_SAMA_FUNC_GPIO | \ - PAL_SAMA_DIR_INPUT | \ - PAL_SAMA_OPD_OPENDRAIN | \ - PAL_SAMA_PUEN_PULLUP - -#define PAD_OUTPUT_MODE PAL_SAMA_FUNC_GPIO | \ - PAL_SAMA_DIR_OUTPUT | \ - PAL_SAMA_OPD_OPENDRAIN | \ - PAL_SAMA_PUEN_PULLUP -#endif /* SAMA_HAL_IS_SECURE */ - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Set ONEWIRE pin in output mode. - * - * @param[in] onewp pointer to a ONEWIRE driver. - * - * @notapi - */ -#define onewireSetPinOutput(onewp) { \ - palSetLineMode(onewp->config->line, PAD_OUTPUT_MODE); \ -} - -/** - * @brief Set ONEWIRE pin in input mode. - * - * @param[in] onewp pointer to a ONEWIRE driver. - * - * @notapi - */ -#define onewireSetPinInput(onewp) { \ - palSetLineMode(onewp->config->line, PAD_INPUT_MODE); \ -} - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -ONEWIREDriver ONEWD0; - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Low level ONEWIRE driver initialization. - * - * @notapi - */ -void onewire_lld_init(void) { - - onewireObjectInit(&ONEWD0); -} - -/** - * @brief Configures and activates the ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * - * @notapi - */ -void onewire_lld_start(ONEWIREDriver *onewp) { - - /* Set the ONEWIRE pin in output mode. */ - onewireSetPinOutput(onewp); - -} - -/** - * @brief Deactivates the ONEWIRE driver. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * - * @notapi - */ -void onewire_lld_stop(ONEWIREDriver *onewp) { - (void) onewp; -} - -/** - * @brief Send a Reset on ONEWIRE pin. - * The reset detect the slave presence on the pin - * and ready it for a command. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @return result result of the reset, if 0 a slave is detected - * - * @notapi - */ -bool onewire_lld_reset(ONEWIREDriver *onewp) { - - bool result = TRUE; - - /* At the beginning set the pin in output mode. */ - onewireSetPinOutput(onewp); - - /* Wait 0 microseconds. */ - chSysPolledDelayX(G); - /* Drives pin low. */ - palClearLine(onewp->config->line); - /* Wait 480 microseconds. */ - chSysPolledDelayX(H); - /* Drives pin high. */ - palSetLine(onewp->config->line); - /* Wait 70 microseconds. */ - chSysPolledDelayX(I); - /* Set the pin in input mode. */ - onewireSetPinInput(onewp); - /* Read the pin logic state. */ - result = palReadLine(onewp->config->line); - /* Wait 410 microseconds. */ - chSysPolledDelayX(J); - - return result; -} - -/** - * @brief Write a bit through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] value bit value to write - * - * @notapi - */ -void onewire_lld_write_bit(ONEWIREDriver *onewp, uint8_t value) { - - osalDbgAssert((value == 0u) || (value == 1u), - "invalid value"); - - /* Set the pin in output mode. */ - onewireSetPinOutput(onewp); - - if (value) { - /* Write '1' bit */ - /* Drives pin low. */ - palClearLine(onewp->config->line); - /* Wait 6 microsecond. */ - chSysPolledDelayX(A); - /* Drives pin high. */ - palSetLine(onewp->config->line); - /* Wait 64 microseconds to complete the time slot and recovery. */ - chSysPolledDelayX(B); - } - else { - /* Write '0' bit */ - /* Drives pin low. */ - palClearLine(onewp->config->line); - /* Wait 60 microsecond. */ - chSysPolledDelayX(C); - /* Drives pin high. */ - palSetLine(onewp->config->line); - /* Wait 10 microseconds for recovery. */ - chSysPolledDelayX(D); - } -} - -/** - * @brief Read a bit through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @return value bit read - * - * @notapi - */ -uint8_t onewire_lld_read_bit(ONEWIREDriver *onewp) { - - uint8_t value; - - /* At the beginning set the pin in output mode. */ - onewireSetPinOutput(onewp); - - /* Drives pin low. */ - palClearLine(onewp->config->line); - /* Wait 6 microsecond. */ - chSysPolledDelayX(A); - /* Drives pin high. */ - palSetLine(onewp->config->line); - /* Wait 9 microseconds. */ - chSysPolledDelayX(E); - /* Set the pin in input mode. */ - onewireSetPinInput(onewp); - /* Read the pin logic state. */ - value = palReadLine(onewp->config->line); - /* Wait 55 microseconds. */ - chSysPolledDelayX(F); - - return value; -} - -/** - * @brief Write a byte through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] byte byte to write - * - * @notapi - */ -void onewire_lld_write_byte(ONEWIREDriver *onewp, uint8_t byte) { - - uint8_t i; - - /* Loop to write each bit in the byte, LS-bit first */ - for (i = 0; i < 8; i++) { - onewire_lld_write_bit(onewp, (byte & 0x01)); - /* Shift the data byte for the next bit */ - byte >>= 1; - } -} - -/** - * @brief Read a byte through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * return value byte read - * - * @notapi - */ -uint8_t onewire_lld_read_byte(ONEWIREDriver *onewp) { - - uint8_t i; - uint8_t value = 0; - - for (i = 0; i < 8; i++) { - /* Shift the result to get it ready for the next bit */ - value >>= 1; - /* If result is one, then set MS bit */ - if (onewire_lld_read_bit(onewp)) - value |= 0x80; - } - return value; -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ -/** - * @brief ONEWIRE driver initialization. - * - * @api - */ -void onewireInit(void) { - - onewire_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p ONEWIREDriver structure. - * - * @param[out] onewp pointer to the @p ONEWIREDriver object - * - * @init - */ -void onewireObjectInit(ONEWIREDriver *onewp) { - - onewp->state = ONEW_STOP; - onewp->config = NULL; - - osalMutexObjectInit(&onewp->mutex); -} - -/** - * @brief Configures and activates the ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] config pointer to the @p ONEWIREConfig object - * - * @api - */ -void onewireStart(ONEWIREDriver *onewp, const ONEWIREConfig *config) { - - osalDbgCheck((onewp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((onewp->state == ONEW_STOP) || (onewp->state == ONEW_READY), - "invalid state"); - onewp->config = config; - onewire_lld_start(onewp); - onewp->state = ONEW_READY; - osalSysUnlock(); - -} - -/** - * @brief Deactivates the ONEWIRE driver. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * - * @api - */ -void onewireStop(ONEWIREDriver *onewp) { - - osalDbgCheck(onewp != NULL); - - osalSysLock(); - - osalDbgAssert((onewp->state == ONEW_STOP) || (onewp->state == ONEW_READY), - "invalid state"); - - onewire_lld_stop(onewp); - onewp->config = NULL; - onewp->state = ONEW_STOP; - - osalSysUnlock(); -} - -/** - * @brief Write a block of bytes through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] txbuf the pointer to the transmit buffer - * @param[in] n number of bytes to write - * - * @api - */ -void onewireWriteBlockI(ONEWIREDriver *onewp, uint8_t *txbuf, size_t n) { - - uint32_t i; - (onewp)->state = ONEW_ACTIVE; - for (i = 0; i < n; i++) { - onewire_lld_write_byte(onewp, txbuf[i]); - } -} - -/** - * @brief Write a block of bytes through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] txbuf the pointer to the transmit buffer - * @param[in] n number of bytes to write - * - * @api - */ -void onewireWriteBlock(ONEWIREDriver *onewp, uint8_t *txbuf, size_t n) { - - osalDbgCheck(onewp != NULL); - - osalSysLock(); - osalDbgAssert(onewp->state == ONEW_READY, "not ready"); - onewireWriteBlockI(onewp, txbuf, n); - - (onewp)->state = ONEW_READY; - osalSysUnlock(); -} - -/** - * @brief Read a block of bytes through ONEWIRE pin. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[out]rxbuf pointer to the receive buffer - * @param[in] n number of bytes to read - * - * @api - */ -void onewireReadBlockI(ONEWIREDriver *onewp, uint8_t *rxbuf, size_t n) { - - uint32_t i; - (onewp)->state = ONEW_ACTIVE; - for (i = 0; i < n; i++) { - rxbuf[i] = onewire_lld_read_byte(onewp); - } -} - -/** - * @brief Read a block of bytes through ONEWIRE pin. - * - * @param[in] onewirep pointer to the @p ONEWIREDriver object - * @param[out]rxbuf pointer to the receive buffer - * @param[in] n number of bytes to read - * - * @api - */ -void onewireReadBlock(ONEWIREDriver *onewp, uint8_t *rxbuf, size_t n) { - - osalDbgCheck(onewp != NULL); - -// osalSysLock(); - osalDbgAssert(onewp->state == ONEW_READY, "not ready"); - onewireReadBlockI(onewp, rxbuf, n); - (onewp)->state = ONEW_READY; -// osalSysUnlock(); -} - -/** - * @brief Send a Reset on ONEWIRE pin. - * The reset detect the slave presence on the pin - * and ready it for a command. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @return result result of the reset, if 0 a slave is detected - * - * @api - */ -bool onewireReset(ONEWIREDriver *onewp) { - - bool detect = TRUE; - - osalDbgCheck(onewp != NULL); - - osalSysLock(); - osalDbgAssert(onewp->state == ONEW_READY, - "invalid state"); - detect = onewire_lld_reset(onewp); - osalSysUnlock(); - - return detect; -} - -/* - * @brief Sends a command. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] cmdp pointer command byte - * - * @api - */ -void onewireCommandI(ONEWIREDriver *onewp, uint8_t *cmdp, size_t n) { - - uint32_t i; - (onewp)->state = ONEW_ACTIVE; - for (i = 0; i < n; i++) { - onewire_lld_write_byte(onewp, cmdp[i]); - } -} - -/* - * @brief Sends a command. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * @param[in] cmdp pointer to command - * - * @api - */ -void onewireCommand(ONEWIREDriver *onewp, uint8_t *cmdp, size_t n) { - - osalDbgCheck((onewp != NULL) && (cmdp != NULL)); - -// osalSysLock(); - - osalDbgAssert(onewp->state == ONEW_READY, "not ready"); - - onewireCommandI(onewp, cmdp, n); - (onewp)->state = ONEW_READY; -// osalSysUnlock(); -} - - -/** - * @brief Gains exclusive access to the ONEWIRE bus. - * @details This function tries to gain ownership to the ONEWIRE bus, if the bus - * is already being used then the invoking thread is queued. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * - * @api - */ -void onewireAcquireBus(ONEWIREDriver *onewp) { - - osalDbgCheck(onewp != NULL); - - osalMutexLock(&onewp->mutex); -} - -/** - * @brief Releases exclusive access to the ONEWIRE bus. - * - * @param[in] onewp pointer to the @p ONEWIREDriver object - * - * @api - */ -void onewireReleaseBus(ONEWIREDriver *onewp) { - - osalDbgCheck(onewp != NULL); - - osalMutexUnlock(&onewp->mutex); -} - -#endif /* SAMA_USE_ONEWIRE == TRUE */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.h b/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.h deleted file mode 100644 index b8edb1185..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_onewire.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_onewire.h - * @brief SAMA ONEWIRE support macros and structures. - * - * @addtogroup SAMA5D2x_ONEWIRE - * @{ - */ - -#ifndef SAMA_ONEWIRE_LLD_H -#define SAMA_ONEWIRE_LLD_H - -/** - * @brief Using the ONEWIRE driver. - */ -#if !defined(SAMA_USE_ONEWIRE) || defined(__DOXYGEN__) -#define SAMA_USE_ONEWIRE FALSE -#endif - -#if (SAMA_USE_ONEWIRE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ -/** - * @brief Driver state machine possible states. - */ -typedef enum { - ONEW_UNINIT = 0, /**< Not initialized. */ - ONEW_STOP = 1, /**< Stopped. */ - ONEW_READY = 2, /**< Active. */ - ONEW_ACTIVE = 3 /**< Active. */ -} onewstate_t; - -/** - * @brief Type of a structure representing a ONEWIRE driver. - */ -typedef struct ONEWIREDriver ONEWIREDriver; - -/** - * @brief Driver configuration structure. - */ -typedef struct { - /** - * @brief Line for the data IO - */ - uint32_t line; -} ONEWIREConfig; - - -/** - * @brief Structure representing an ONEWIRE driver. - */ -struct ONEWIREDriver { - /** - * @brief Driver state. - */ - onewstate_t state; - /** - * @brief Current configuration data. - */ - const ONEWIREConfig *config; - /** - * @brief Mutex protecting the bus. - */ - mutex_t mutex; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -extern ONEWIREDriver ONEWD0; - -#ifdef __cplusplus -extern "C" { -#endif - void onewireInit(void); - void onewireObjectInit(ONEWIREDriver *onewp); - void onewireStart(ONEWIREDriver *onewp, const ONEWIREConfig *config); - void onewireStop(ONEWIREDriver *onewp); - bool onewireReset(ONEWIREDriver *onewp); - void onewireCommand(ONEWIREDriver *onewp, uint8_t *cmdp, size_t n); - void onewireWriteBlock(ONEWIREDriver *onewp, uint8_t *txbuf, size_t n); - void onewireReadBlock(ONEWIREDriver *onewp, uint8_t *rxbuf, size_t n); - void onewireAcquireBus(ONEWIREDriver *onewp); - void onewireReleaseBus(ONEWIREDriver *onewp); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_USE_ONEWIRE */ - -#endif /* SAMA_ONEWIRE_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h b/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h deleted file mode 100644 index bf0fb7441..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h +++ /dev/null @@ -1,1030 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_pmc.h - * @brief PMC helper driver header. - * - * @addtogroup SAMA5D2x_PMC - * @{ - */ - -#ifndef _SAMA_PMC_ -#define _SAMA_PMC_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @name Generic PMC operations - * @{ - */ -#if SAMA_HAL_IS_SECURE -/** - * @brief Enable write protection on PMC registers block. - * - * @notapi - */ -#define pmcEnableWP() { \ - PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on PMC registers block. - * - * @notapi - */ -#define pmcDisableWP() { \ - PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD; \ -} - -/** - * @brief Enables the clock of one or more peripheral having ID from 2 to - * 31. - * - * @param[in] mask PCER0 peripherals mask - * - * @api - */ -#define pmcEnablePidLow(mask) { \ - pmcDisableWP(); \ - PMC->PMC_PCER0 = (mask); \ - pmcEnableWP(); \ -} - -/** - * @brief Disables the clock of one or more peripheral having ID from 2 to - * 31. - * - * @param[in] mask PCDR0 peripherals mask - * - * @api - */ -#define pmcDisablePidLow(mask) { \ - pmcDisableWP(); \ - PMC->PMC_PCDR0 = (mask); \ - pmcEnableWP(); \ -} - -/** - * @brief Enables the clock of one or more peripheral having ID from 32 to - * 63. - * - * @param[in] mask PCER1 peripherals mask - * - * @api - */ -#define pmcEnablePidHigh(mask) { \ - pmcDisableWP(); \ - PMC->PMC_PCER1 = (mask); \ - pmcEnableWP(); \ -} - -/** - * @brief Disables the clock of one or more peripheral having ID from 32 to - * 63. - * - * @param[in] mask PCDR1 peripherals mask - * - * @api - */ -#define pmcDisablePidHigh(mask) { \ - pmcDisableWP(); \ - PMC->PMC_PCDR1 = (mask); \ - pmcEnableWP(); \ -} - -/** - * @brief Enables the generic clock of a peripheral. - * - * @param[in] mask ID peripherals - * - * @api - */ -#define pmcEnableGclk(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - pmcDisableWP(); \ - PMC->PMC_PCR = PMC_PCR_PID(id); \ - uint32_t pcr = PMC->PMC_PCR; \ - PMC->PMC_PCR = pcr | PMC_PCR_CMD | PMC_PCR_GCKEN; \ - while (!(PMC->PMC_SR & PMC_SR_GCKRDY)); \ - pmcEnableWP(); \ -} - -/** - * @brief Disable the generic clock of a peripheral. - * - * @param[in] mask ID peripherals - * - * @api - */ -#define pmcDisableGclk(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - pmcDisableWP(); \ - PMC->PMC_PCR = PMC_PCR_PID(id); \ - uint32_t pcr = PMC->PMC_PCR; \ - PMC->PMC_PCR = PMC_PCR_CMD | (pcr & ~(PMC_PCR_GCKEN)); \ - pmcEnableWP(); \ -} - -/** - * @brief Configure the generic clock of a peripheral. - * - * @param[in] id ID peripherals mask - * @param[in] clock_source Clock source - * @param[in] div Divider - * - * @api - */ - -#define pmcConfigGclk(id, clock_source, div) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - osalDbgCheck(!(clock_source & ~PMC_PCR_GCKCSS_Msk)); \ - osalDbgCheck((div > 0)); \ - osalDbgCheck(!(div << PMC_PCR_GCKDIV_Pos & ~PMC_PCR_GCKDIV_Msk)); \ - pmcDisableGclk(id); \ - pmcDisableWP(); \ - PMC->PMC_PCR = PMC_PCR_PID(id); \ - uint32_t pcr = PMC->PMC_PCR & ~(PMC_PCR_GCKCSS_Msk | PMC_PCR_GCKDIV_Msk); \ - PMC->PMC_PCR = pcr | clock_source | PMC_PCR_CMD | PMC_PCR_GCKDIV(div - 1);\ - pmcEnableWP(); \ -} - -/** - * @brief Enable the peripheral clock of a peripheral. - * - * @param[in] id ID peripherals mask - * - * @api - */ -#define pmcEnablePeripheral(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - pmcDisableWP(); \ - PMC->PMC_PCR = PMC_PCR_PID(id); \ - uint32_t pcr = PMC->PMC_PCR; \ - PMC->PMC_PCR = pcr | PMC_PCR_CMD | PMC_PCR_EN; \ - pmcEnableWP(); \ -} - -/** - * @brief Disable the peripheral clock of a peripheral. - * - * @param[in] id ID peripherals mask - * - * @api - */ -#define pmcDisablePeripheral(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - pmcDisableWP(); \ - PMC->PMC_PCR = PMC_PCR_PID(id); \ - PMC->PMC_PCR = (PMC->PMC_PCR & ~PMC_PCR_EN) | PMC_PCR_CMD; \ - pmcEnableWP(); \ -} - - -/** - * @brief Configure the Audio clock. - * - * @param[in] nd Loop Divider Ratio - * @param[in] qdpmc Output Divider Ratio for PMC Clock - * @param[in] fracr Fractional Loop Divider Setting - * @param[in] div Divider Value - * @param[in] qaudio Output Divider Ratio for Pad Clock - * - * @api - */ -#define pmcConfigAudio(nd,qdpmc,fracr,div,qdaudio) { \ - /* Reset audio clock */ \ - pmcDisableWP(); \ - PMC->PMC_AUDIO_PLL0 &= ~PMC_AUDIO_PLL0_RESETN; \ - PMC->PMC_AUDIO_PLL0 |= PMC_AUDIO_PLL0_RESETN; \ - /* Configure values */ \ - PMC->PMC_AUDIO_PLL0 = (PMC->PMC_AUDIO_PLL0 & \ - ~PMC_AUDIO_PLL0_PLLFLT_Msk & \ - ~PMC_AUDIO_PLL0_ND_Msk & \ - ~PMC_AUDIO_PLL0_QDPMC_Msk) | \ - PMC_AUDIO_PLL0_PLLFLT_STD | \ - PMC_AUDIO_PLL0_ND(nd) | \ - PMC_AUDIO_PLL0_QDPMC(qdpmc); \ - PMC->PMC_AUDIO_PLL1 = (PMC->PMC_AUDIO_PLL1 & \ - ~PMC_AUDIO_PLL1_FRACR_Msk & \ - ~PMC_AUDIO_PLL1_DIV_Msk & \ - ~PMC_AUDIO_PLL1_QDAUDIO_Msk) | \ - PMC_AUDIO_PLL1_FRACR(fracr) | \ - PMC_AUDIO_PLL1_DIV(div)| \ - PMC_AUDIO_PLL1_QDAUDIO(qdaudio); \ - pmcEnableWP(); \ -} - -/** - * @brief Enable the audio clock of a audio peripheral. - * - * @param[in] pmcClock If set TRUE enable the PMC clock - * @param[in] padClock If set TRUE enable the PAD clock - * - * @api - */ -#define pmcEnableAudio(pmcClock, padClock) { \ - pmcDisableWP(); \ - uint32_t bits = PMC_AUDIO_PLL0_PLLEN | PMC_AUDIO_PLL0_RESETN; \ - uint32_t nbits = 0; \ - if(padClock) \ - bits |= PMC_AUDIO_PLL0_PADEN; \ - else \ - nbits |= PMC_AUDIO_PLL0_PADEN; \ - if(pmcClock) \ - bits |= PMC_AUDIO_PLL0_PMCEN; \ - else \ - nbits |= PMC_AUDIO_PLL0_PMCEN; \ - PMC->PMC_AUDIO_PLL0 = (PMC->PMC_AUDIO_PLL0 & ~nbits) | bits; \ - /* Wait for the Audio PLL Startup Time (tSTART = 100 usec) */ \ - chSysPolledDelayX(US2RTC(SAMA_PCK, 100)); \ - pmcEnableWP(); \ -} - -/** - * @brief Disable the audio clock of a audio peripheral. - * - * @api - */ -#define pmcDisableAudio(){ \ - pmcDisableWP(); \ - PMC->PMC_AUDIO_PLL0 &= ~(PMC_AUDIO_PLL0_PLLEN | PMC_AUDIO_PLL0_RESETN | \ - PMC_AUDIO_PLL0_PADEN | PMC_AUDIO_PLL0_PMCEN); \ - pmcEnableWP(); \ -} -#else -#include "tsclient.h" - -static inline uint32_t readPMCr(uint32_t regOffset) -{ - sec_reg_val_t secr; - - secr.reg = regOffset; - secr.value = 0; - (void) tsInvoke0((ts_service_t)TS_FC_PMC_RD, - (ts_params_area_t)&secr, sizeof secr, TS_TIMEINT_1000_US); - return secr.value; -} - -static inline void writePMCr(uint32_t regOffset, uint32_t v) -{ - sec_reg_val_t secr; - - secr.reg = regOffset; - secr.value = v; - (void) tsInvoke0((ts_service_t)TS_FC_PMC_WR, - (ts_params_area_t)&secr, sizeof secr, TS_TIMEINT_1000_US); - return; -} - -/** - * @brief Enables the clock of one or more peripheral having ID from 2 to - * 31. - * - * @param[in] mask PCER0 peripherals mask - * - * @api - */ -#define pmcEnablePidLow(mask) { \ - writePMCr(offsetof(Pmc, PMC_PCER0), (mask)); \ -} - -/** - * @brief Disables the clock of one or more peripheral having ID from 2 to - * 31. - * - * @param[in] mask PCDR0 peripherals mask - * - * @api - */ -#define pmcDisablePidLow(mask) { \ - writePMCr(offsetof(Pmc, PMC_PCDR0), (mask)); \ -} - -/** - * @brief Enables the clock of one or more peripheral having ID from 32 to - * 63. - * - * @param[in] mask PCER1 peripherals mask - * - * @api - */ -#define pmcEnablePidHigh(mask) { \ - writePMCr(offsetof(Pmc, PMC_PCER1), (mask)); \ -} - -/** - * @brief Disables the clock of one or more peripheral having ID from 32 to - * 63. - * - * @param[in] mask PCDR1 peripherals mask - * - * @api - */ -#define pmcDisablePidHigh(mask) { \ - writePMCr(offsetof(Pmc, PMC_PCDR1), (mask)); \ -} - -/** - * @brief Enables the generic clock of a peripheral. - * - * @param[in] mask ID peripherals - * - * @api - */ -#define pmcEnableGclk(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - writePMCr(offsetof(Pmc, PMC_PCR), PMC_PCR_PID(id)); \ - uint32_t pcr = readPMCr(offsetof(Pmc, PMC_PCR)); \ - writePMCr(offsetof(Pmc, PMC_PCR), pcr | PMC_PCR_CMD | PMC_PCR_GCKEN); \ - while (!(readPMCr(offsetof(Pmc, PMC_SR)) & PMC_SR_GCKRDY)); \ -} - -/** - * @brief Disable the generic clock of a peripheral. - * - * @param[in] mask ID peripherals - * - * @api - */ -#define pmcDisableGclk(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - writePMCr(offsetof(Pmc, PMC_PCR), PMC_PCR_PID(id)); \ - uint32_t pcr = readPMCr(offsetof(Pmc, PMC_PCR)); \ - writePMCr(offsetof(Pmc, PMC_PCR), PMC_PCR_CMD | (pcr & ~(PMC_PCR_GCKEN)));\ -} - -/** - * @brief Configure the generic clock of a peripheral. - * - * @param[in] id ID peripherals mask - * @param[in] clock_source Clock source - * @param[in] div Divider - * - * @api - */ - -#define pmcConfigGclk(id, clock_source, div) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - osalDbgCheck(!(clock_source & ~PMC_PCR_GCKCSS_Msk)); \ - osalDbgCheck((div > 0)); \ - osalDbgCheck(!(div << PMC_PCR_GCKDIV_Pos & ~PMC_PCR_GCKDIV_Msk)); \ - pmcDisableGclk(id); \ - writePMCr(offsetof(Pmc, PMC_PCR), PMC_PCR_PID(id)); \ - uint32_t pcr = readPMCr(offsetof(Pmc, PMC_PCR) & ~(PMC_PCR_GCKCSS_Msk | PMC_PCR_GCKDIV_Msk); \ - writePMCr(offsetof(Pmc, PMC_PCR), pcr | clock_source | PMC_PCR_CMD | PMC_PCR_GCKDIV(div - 1));\ -} - -/** - * @brief Enable the peripheral clock of a peripheral. - * - * @param[in] id ID peripherals mask - * - * @api - */ -#define pmcEnablePeripheral(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - writePMCr(offsetof(Pmc, PMC_PCR), PMC_PCR_PID(id)); \ - uint32_t pcr = readPMCr(offsetof(Pmc, PMC_PCR)); \ - writePMCr(offsetof(Pmc, PMC_PCR), pcr | PMC_PCR_CMD | PMC_PCR_EN); \ -} - -/** - * @brief Disable the peripheral clock of a peripheral. - * - * @param[in] id ID peripherals mask - * - * @api - */ -#define pmcDisablePeripheral(id) { \ - osalDbgCheck(id < ID_PERIPH_COUNT); \ - writePMCr(offsetof(Pmc, PMC_PCR), PMC_PCR_PID(id)); \ - uint32_t pcr = readPMCr(offsetof(Pmc, PMC_PCR)); \ - writePMCr(offsetof(Pmc, PMC_PCR), (pcr & ~PMC_PCR_EN) | PMC_PCR_CMD); \ -} - - -/** - * @brief Configure the Audio clock. - * - * @param[in] nd Loop Divider Ratio - * @param[in] qdpmc Output Divider Ratio for PMC Clock - * @param[in] fracr Fractional Loop Divider Setting - * @param[in] div Divider Value - * @param[in] qaudio Output Divider Ratio for Pad Clock - * - * @api - */ -#define pmcConfigAudio(nd,qdpmc,fracr,div,qdaudio) { \ - /* Reset audio clock */ \ - writePMCr(offsetof(Pmc, PMC_AUDIO_PLL0), readPMCr(offsetof(Pmc, PMC_AUDIO_PLL0)) & ~PMC_AUDIO_PLL0_RESETN);\ - writePMCr(offsetof(Pmc, PMC_AUDIO_PLL0), readPMCr(offsetof(Pmc, PMC_AUDIO_PLL0)) | PMC_AUDIO_PLL0_RESETN);\ - /* Configure values */ \ - writePMCr(offsetof(Pmc, PMC_AUDIO_PLL0), (readPMCr(offsetof(Pmc, PMC_AUDIO_PLL0)) &\ - ~PMC_AUDIO_PLL0_PLLFLT_Msk & \ - ~PMC_AUDIO_PLL0_ND_Msk & \ - ~PMC_AUDIO_PLL0_QDPMC_Msk) | \ - PMC_AUDIO_PLL0_PLLFLT_STD | \ - PMC_AUDIO_PLL0_ND(nd) | \ - PMC_AUDIO_PLL0_QDPMC(qdpmc)); \ - writePMCr(offsetof(Pmc, PMC_AUDIO_PLL1), (readPMCr(offsetof(Pmc, PMC_AUDIO_PLL1)) &\ - ~PMC_AUDIO_PLL1_FRACR_Msk & \ - ~PMC_AUDIO_PLL1_DIV_Msk & \ - ~PMC_AUDIO_PLL1_QDAUDIO_Msk) | \ - PMC_AUDIO_PLL1_FRACR(fracr) | \ - PMC_AUDIO_PLL1_DIV(div)| \ - PMC_AUDIO_PLL1_QDAUDIO(qdaudio)); \ -} - -/** - * @brief Enable the audio clock of a audio peripheral. - * - * @param[in] pmcClock If set TRUE enable the PMC clock - * @param[in] padClock If set TRUE enable the PAD clock - * - * @api - */ -#define pmcEnableAudio(pmcClock, padClock) { \ - uint32_t bits = PMC_AUDIO_PLL0_PLLEN | PMC_AUDIO_PLL0_RESETN; \ - uint32_t nbits = 0; \ - if(padClock) \ - bits |= PMC_AUDIO_PLL0_PADEN; \ - else \ - nbits |= PMC_AUDIO_PLL0_PADEN; \ - if(pmcClock) \ - bits |= PMC_AUDIO_PLL0_PMCEN; \ - else \ - nbits |= PMC_AUDIO_PLL0_PMCEN; \ - writePMCr(offsetof(Pmc, PMC_AUDIO_PLL0), (readPMCr(offsetof(Pmc, PMC_AUDIO_PLL0)) & ~nbits) | bits);\ - /* Wait for the Audio PLL Startup Time (tSTART = 100 usec) */ \ - chSysPolledDelayX(US2RTC(SAMA_PCK, 100)); \ -} - -/** - * @brief Disable the audio clock of a audio peripheral. - * - * @api - */ -#define pmcDisableAudio(){ \ - writePMCr(offsetof(Pmc, PMC_AUDIO_PLL0), readPMCr(offsetof(Pmc, PMC_AUDIO_PLL0)) & \ - ~(PMC_AUDIO_PLL0_PLLEN | PMC_AUDIO_PLL0_RESETN | \ - PMC_AUDIO_PLL0_PADEN | PMC_AUDIO_PLL0_PMCEN)); \ -} - -#endif - -/** @} */ - -/** - * @name ADC peripherals specific PMC operations - * @{ - */ -/** - * @brief Enables the PIT peripheral clock. - * - * @api - */ -#define pmcEnablePIT() pmcEnablePidLow(ID_PIT_MSK) - -/** - * @brief Disables the PIT peripheral clock. - * - * @api - */ -#define pmcDisablePIT() pmcDisablePidLow(ID_PIT_MSK) - -/** - * @brief Enables the XDMAC0 peripheral clock. - * - * @api - */ -#define pmcEnableXDMAC0() pmcEnablePidLow(ID_XDMAC0_MSK) - -/** - * @brief Disables the XDMAC0 peripheral clock. - * - * @api - */ -#define pmcDisableXDMAC0() pmcDisablePidLow(ID_XDMAC0_MSK) - -/** - * @brief Enables the XDMAC1 peripheral clock. - * - * @api - */ -#define pmcEnableXDMAC1() pmcEnablePidLow(ID_XDMAC1_MSK) - -/** - * @brief Disables the XDMAC1 peripheral clock. - * - * @api - */ -#define pmcDisableXDMAC1() pmcDisablePidLow(ID_XDMAC1_MSK) - -/** - * @brief Enables the H32MX peripheral clock. - * - * @api - */ -#define pmcEnableH32MX() pmcEnablePidLow(ID_MATRIX1_MSK) - -/** - * @brief Disables the H32MX peripheral clock. - * - * @api - */ -#define pmcDisableH32MX() pmcDisablePidLow(ID_MATRIX1_MSK) - -/** - * @brief Enables the H64MX peripheral clock. - * - * @api - */ -#define pmcEnableH64MX() pmcEnablePidLow(ID_MATRIX0_MSK) - -/** - * @brief Disables the H64MX peripheral clock. - * - * @api - */ -#define pmcDisableH64MX() pmcDisablePidLow(ID_MATRIX0_MSK) - -/** - * @brief Enables the PIO peripheral clock. - * - * @api - */ -#define pmcEnablePIO() pmcEnablePidLow(ID_PIOA_MSK) - -/** - * @brief Disables the PIO peripheral clock. - * - * @api - */ -#define pmcDisablePIO() pmcDisablePidLow(ID_PIOA_MSK) - -/** - * @brief Enables the SPI0 peripheral clock. - * - * @api - */ -#define pmcEnableSPI0() pmcEnablePidHigh(ID_SPI0_MSK) - -/** - * @brief Disables the SPI0 peripheral clock. - * - * @api - */ -#define pmcDisableSPI0() pmcDisablePidHigh(ID_SPI0_MSK) - -/** - * @brief Enables the SPI1 peripheral clock. - * - * @api - */ -#define pmcEnableSPI1() pmcEnablePidHigh(ID_SPI1_MSK) - -/** - * @brief Disables the SPI11 peripheral clock. - * - * @api - */ -#define pmcDisableSPI1() pmcDisablePidHigh(ID_SPI1_MSK) - -/** - * @brief Enables the UART0 peripheral clock. - * - * @api - */ -#define pmcEnableUART0() pmcEnablePidLow(ID_UART0_MSK) - -/** - * @brief Disables the UART0 peripheral clock. - * - * @api - */ -#define pmcDisableUART0() pmcDisablePidLow(ID_UART0_MSK) - -/** - * @brief Enables the UART1 peripheral clock. - * - * @api - */ -#define pmcEnableUART1() pmcEnablePidLow(ID_UART1_MSK) - -/** - * @brief Disables the UART1 peripheral clock. - * - * @api - */ -#define pmcDisableUART1() pmcDisablePidLow(ID_UART1_MSK) - -/** - * @brief Enables the UART2 peripheral clock. - * - * @api - */ -#define pmcEnableUART2() pmcEnablePidLow(ID_UART2_MSK) - -/** - * @brief Disables the UART2 peripheral clock. - * - * @api - */ -#define pmcDisableUART2() pmcDisablePidLow(ID_UART2_MSK) - -/** - * @brief Enables the UART3 peripheral clock. - * - * @api - */ -#define pmcEnableUART3() pmcEnablePidLow(ID_UART3_MSK) - -/** - * @brief Disables the UART3 peripheral clock. - * - * @api - */ -#define pmcDisableUART3() pmcDisablePidLow(ID_UART3_MSK) - -/** - * @brief Enables the UART4 peripheral clock. - * - * @api - */ -#define pmcEnableUART4() pmcEnablePidLow(ID_UART4_MSK) - -/** - * @brief Disables the UART4 peripheral clock. - * - * @api - */ -#define pmcDisableUART4() pmcDisablePidLow(ID_UART4_MSK) - -/** - * @brief Enables the FLEXCOM0 peripheral clock. - * - * @api - */ -#define pmcEnableFLEXCOM0() pmcEnablePidLow(ID_FLEXCOM0_MSK) - -/** - * @brief Disables the FLEXCOM0 peripheral clock. - * - * @api - */ -#define pmcDisableFLEXCOM0() pmcDisablePidLow(ID_FLEXCOM0_MSK) - -/** - * @brief Enables the FLEXCOM1 peripheral clock. - * - * @api - */ -#define pmcEnableFLEXCOM1() pmcEnablePidLow(ID_FLEXCOM1_MSK) - -/** - * @brief Disables the FLEXCOM1 peripheral clock. - * - * @api - */ -#define pmcDisableFLEXCOM1() pmcDisablePidLow(ID_FLEXCOM1_MSK) - -/** - * @brief Enables the FLEXCOM2 peripheral clock. - * - * @api - */ -#define pmcEnableFLEXCOM2() pmcEnablePidLow(ID_FLEXCOM2_MSK) - -/** - * @brief Disables the FLEXCOM2 peripheral clock. - * - * @api - */ -#define pmcDisableFLEXCOM2() pmcDisablePidLow(ID_FLEXCOM2_MSK) - -/** - * @brief Enables the FLEXCOM0 peripheral clock. - * - * @api - */ -#define pmcEnableFLEXCOM3() pmcEnablePidLow(ID_FLEXCOM3_MSK) - -/** - * @brief Disables the FLEXCOM3 peripheral clock. - * - * @api - */ -#define pmcDisableFLEXCOM3() pmcDisablePidLow(ID_FLEXCOM3_MSK) - -/** - * @brief Enables the FLEXCOM4 peripheral clock. - * - * @api - */ -#define pmcEnableFLEXCOM4() pmcEnablePidLow(ID_FLEXCOM4_MSK) - -/** - * @brief Disables the FLEXCOM4 peripheral clock. - * - * @api - */ -#define pmcDisableFLEXCOM4() pmcDisablePidLow(ID_FLEXCOM4_MSK) - -/** - * @brief Enables the TC0 peripheral clock. - * - * @api - */ -#define pmcEnableTC0() pmcEnablePidHigh(ID_TC0_MSK) - -/** - * @brief Disables the TC0 peripheral clock. - * - * @api - */ -#define pmcDisableTC0() pmcDisablePidHigh(ID_TC0_MSK) - -/** - * @brief Enables the TC1 peripheral clock. - * - * @api - */ -#define pmcEnableTC1() pmcEnablePidHigh(ID_TC1_MSK) - -/** - * @brief Disables the TC1 peripheral clock. - * - * @api - */ -#define pmcDisableTC1() pmcDisablePidHigh(ID_TC1_MSK) - - -/** - * @brief Enables the AES peripheral clock. - * - * @api - */ -#define pmcEnableAES() pmcEnablePidLow(ID_AES_MSK) - -/** - * @brief Disables the AES peripheral clock. - * - * @api - */ -#define pmcDisableAES() pmcDisablePidLow(ID_AES_MSK) - -/** - * @brief Enables the TRNG peripheral clock. - * - * @api - */ -#define pmcEnableTRNG() pmcEnablePidHigh(ID_TRNG_MSK) -/** - * @brief Disables the TRNG peripheral clock. - * - * @api - */ -#define pmcDisableTRNG() pmcDisablePidHigh(ID_TRNG_MSK) - -/** - * @brief Enables the DES peripheral clock. - * - * @api - */ -#define pmcEnableDES() pmcEnablePidLow(ID_TDES_MSK) -/** - * @brief Disables the DES peripheral clock. - * - * @api - */ -#define pmcDisableDES() pmcDisablePidLow(ID_TDES_MSK) - -/** - * @brief Enables the SHA peripheral clock. - * - * @api - */ -#define pmcEnableSHA() pmcEnablePidLow(ID_SHA_MSK) -/** - * @brief Disables the SHA peripheral clock. - * - * @api - */ -#define pmcDisableSHA() pmcDisablePidLow(ID_SHA_MSK) - -/** - * @brief Enables the ETH0 peripheral clock. - * - * @api - */ -#define pmcEnableETH0() pmcEnablePidLow(ID_GMAC0_MSK) - -/** - * @brief Disables the ETH0 peripheral clock. - * - * @api - */ -#define pmcDisableETH0() pmcDisablePidLow(ID_GMAC0_MSK) - -/** - * @brief Enables the SECUMOD peripheral clock. - * - * @api - */ -#define pmcEnableSEC() pmcEnablePidLow(ID_SECUMOD_MSK) - -/** - * @brief Disables the SECUMOD peripheral clock. - * - * @api - */ -#define pmcDisableSEC() pmcDisablePidLow(ID_SECUMOD_MSK) - -/** - * @brief Enables the SDMMC0 peripheral clock. - * - * @api - */ -#define pmcEnableSDMMC0() pmcEnablePidLow(ID_SDMMC0_MSK) - -/** - * @brief Disables the SDMMC0 peripheral clock. - * - * @api - */ -#define pmcDisableSDMMC0() pmcDisablePidLow(ID_SDMMC0_MSK) - -/** - * @brief Enables the SDMMC1 peripheral clock. - * - * @api - */ -#define pmcEnableSDMMC1() pmcEnablePidHigh(ID_SDMMC1_MSK) - -/** - * @brief Disables the SDMMC1 peripheral clock. - * - * @api - */ -#define pmcDisableSDMMC1() pmcDisablePidHigh(ID_SDMMC1_MSK) - -/** - * @brief Enables the CLASSD peripheral clock. - * - * @api - */ -#define pmcEnableCLASSD0() pmcEnablePidHigh(ID_CLASSD_MSK) - -/** - * @brief Disables the CLASSD peripheral clock. - * - * @api - */ -#define pmcDisableCLASSD0() pmcDisablePidHigh(ID_CLASSD_MSK) - -/** - * @brief Enables the CLASSD generic clock. - * - * @api - */ -#define pmcEnableGclkCLASSD0() pmcEnableGclk(ID_CLASSD) - -/** - * @brief Disables the CLASSD generic clock. - * - * @api - */ -#define pmcDisableGclkCLASSD0() pmcDisableGclk(ID_CLASSD) - -/** - * @brief Enables the TRNG peripheral clock. - * - * @api - */ -#define pmcEnableTRNG0() pmcEnablePidHigh(ID_TRNG_MSK) - -/** - * @brief Disables the TRNG peripheral clock. - * - * @api - */ -#define pmcDisableTRNG0() pmcDisablePidHigh(ID_TRNG_MSK) - -/** - * @brief Enables the QSPI0 peripheral clock. - * - * @api - */ -#define pmcEnableQSPI0() pmcEnablePidHigh(ID_QSPI0_MSK) - -/** - * @brief Disables the QSPI0 peripheral clock. - * - * @api - */ -#define pmcDisableQSPI0() pmcDisablePidHigh(ID_QSPI0_MSK) - -/** - * @brief Enables the QSPI1 peripheral clock. - * - * @api - */ -#define pmcEnableQSPI1() pmcEnablePidHigh(ID_QSPI1_MSK) - -/** - * @brief Disables the QSPI1 peripheral clock. - * - * @api - */ -#define pmcDisableQSPI1() pmcDisablePidHigh(ID_QSPI1_MSK) - -/** - * @brief Enables the LCDC peripheral clock. - * - * @api - */ -#define pmcEnableLCDC() pmcEnablePidHigh(ID_LCDC_MSK) - -/** - * @brief Disables the LCDC peripheral clock. - * - * @api - */ -#define pmcDisableLCDC() pmcDisablePidHigh(ID_LCDC_MSK) - -/** - * @brief Enables the TWIHS0 peripheral clock. - * - * @api - */ -#define pmcEnableTWIHS0() pmcEnablePidLow(ID_TWIHS0_MSK) - -/** - * @brief Disables the TWIHS0 peripheral clock. - * - * @api - */ -#define pmcDisableTWIHS0() pmcDisablePidLow(ID_TWIHS0_MSK) - -/** - * @brief Enables the TWIHS1 peripheral clock. - * - * @api - */ -#define pmcEnableTWIHS1() pmcEnablePidLow(ID_TWIHS1_MSK) - -/** - * @brief Disables the TWIHS1 peripheral clock. - * - * @api - */ -#define pmcDisableTWIHS1() pmcDisablePidLow(ID_TWIHS1_MSK) - -/** @} */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -} -#endif - -#endif /* _SAMA_PMC_ */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_registry.h b/os/hal/ports/SAMA/SAMA5D2x/sama_registry.h deleted file mode 100644 index 31a017707..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_registry.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_registry.h - * @brief SAMA5D2x capabilities registry. - * - * @addtogroup HAL - * @{ - */ - -#ifndef SAMA_REGISTRY_H -#define SAMA_REGISTRY_H - -/** - * @brief Sub-family identifier. - */ -#if !defined(SAMA5D2X) || defined(__DOXYGEN__) -#define SAMA5D2X -#endif - -/*===========================================================================*/ -/* Common features. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Platform capabilities. */ -/*===========================================================================*/ - -/** - * @name SAMA5D27 capabilities - * @{ - */ -/*===========================================================================*/ -/* SAMA5D27. */ -/*===========================================================================*/ - -#if defined(SAMA5D27) || defined(__DOXYGEN__) - -#endif /* defined(SAMA5D27) */ - -/* PIO attributes.*/ -#define SAMA_HAS_PIOA TRUE -#if SAMA_HAL_IS_SECURE -#define PIOA_BASE 0xFC039000U -#else -#define PIOA_BASE 0xFC038000U -#endif - -#define SAMA_HAS_PIOB TRUE -#if SAMA_HAL_IS_SECURE -#define PIOB_BASE 0xFC039040U -#else -#define PIOB_BASE 0xFC038040U -#endif - -#define SAMA_HAS_PIOC TRUE -#if SAMA_HAL_IS_SECURE -#define PIOC_BASE 0xFC039080U -#else -#define PIOC_BASE 0xFC038080U -#endif - -#define SAMA_HAS_PIOD TRUE -#if SAMA_HAL_IS_SECURE -#define PIOD_BASE 0xFC0390C0U -#else -#define PIOD_BASE 0xFC0380C0U -#endif -/** @} */ - -#endif /* SAMA_REGISTRY_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_rstc.h b/os/hal/ports/SAMA/SAMA5D2x/sama_rstc.h deleted file mode 100644 index e390e5eb2..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_rstc.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_rstc.h - * @brief SAMA RSTC helper driver header. - * - * @addtogroup SAMA5D2x_RSTC - * @{ - */ - -#ifndef _SAMA_RSTC_ -#define _SAMA_RSTC_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ -/** - * @name RESET SOURCE MACROS - * @{ - */ -/** - * @brief No access allowed. - */ -#define RSTC_GENERAL 0x0U - -/** - * @brief Only write access allowed. - */ -#define RSTC_WKUP 0x1U - -/** - * @brief Only read access allowed. - */ -#define RSTC_WDT 0x2U - -/** - * @brief Read and Write access allowed. - */ -#define RSTC_SOFT 0x3U - -/** - * @brief Read and Write access allowed. - */ -#define RSTC_USER 0x4U -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @name Generic RSTC operations - * @{ - */ -/** - * @brief Enable/Disable the detection of a low level on the pin NRST - * as User Reset. - * @param[in] enable - */ -#define rstcSetUserResetEnable(enable) { \ - if (enable) { \ - RSTC->RSTC_MR |= RSTC_MR_URSTEN | RSTC_MR_KEY_PASSWD; \ - } else { \ - RSTC->RSTC_MR &= ~RSTC_MR_URSTEN; \ - RSTC->RSTC_MR |= RSTC_MR_KEY_PASSWD; \ - } \ -} - -/** - * @brief Enable/Disable the interrupt of a User Reset. - * @param[in] enable - */ -#define rstcSetUserResetInterruptEnable(enable) { \ - if (enable) { \ - RSTC->RSTC_MR |= RSTC_MR_URSTIEN | RSTC_MR_KEY_PASSWD; \ - } else { \ - RSTC->RSTC_MR &= ~RSTC_MR_URSTIEN; \ - RSTC->RSTC_MR |= RSTC_MR_KEY_PASSWD; \ - } \ -} - -/** - * @brief Perform a processor and peripheral reset. - * - * @notapi - */ -#define rstcResetProcessorAndPeripheral() { \ - RSTC->RSTC_CR = RSTC_CR_PERRST | RSTC_CR_PROCRST | RSTC_MR_KEY_PASSWD; \ -} - -/** - * @brief Perform a processor reset. - * - * @notapi - */ -#define rstcResetProcessor() { \ - RSTC->RSTC_CR = RSTC_CR_PROCRST | RSTC_CR_KEY_PASSWD; \ -} - -/** - * @brief Perform a peripheral reset. - * - * @notapi - */ -#define rstcResetPeripheral() { \ - RSTC->RSTC_CR = RSTC_CR_PERRST | RSTC_MR_KEY_PASSWD; \ -} - -/** - * @brief Report the cause of the last processor reset. - * - * @param[out] status Cause of the reset - * - * @notapi - */ -#define rstcGetStatus(status) { \ - uint32_t sr = RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk; \ - switch (sr) { \ - case RSTC_SR_RSTTYP_GENERAL_RST: \ - status = RSTC_GENERAL; \ - break; \ - case RSTC_SR_RSTTYP_WKUP_RST: \ - status = RSTC_WKUP; \ - break; \ - case RSTC_SR_RSTTYP_WDT_RST: \ - status = RSTC_WDT; \ - break; \ - case RSTC_SR_RSTTYP_SOFT_RST: \ - status = RSTC_SOFT; \ - break; \ - case RSTC_SR_RSTTYP_USER_RST: \ - status = RSTC_USER; \ - break; \ - default: \ - break; \ - } \ -} - -/** @} */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_RSTC_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.c b/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.c deleted file mode 100644 index 35fbab578..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_secumod.c - * @brief SAMA SECUMOD support code. - * - * @addtogroup SAMA5D2x_SECUMOD - * @{ - */ - -#include "hal.h" - -#if SAMA_USE_SECUMOD || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -/** - * @brief SEC driver identifier. - */ -SECDriver SECD0; - -/*===========================================================================*/ -/* Driver local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver constant */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief SECURAM interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SECURAM_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t ramaccsr, sr, sysr; - uint32_t rwx; - uint32_t i; - - ramaccsr = SECUMOD->SECUMOD_RAMACCSR; - sr = SECUMOD->SECUMOD_SR; - - for (i = 0; i < SECUMOD_RAM_REGIONS; i++) { - rwx = (ramaccsr >> (2 * i)) & 3; - if (rwx != RAMACCSR_NO_VIOLATION && SECD0.config->securam_callback != NULL) - SECD0.config->securam_callback(&SECD0); - } - - /* process the end of erase signalling */ - do { - sysr = SECUMOD->SECUMOD_SYSR; - } while (sysr & SECUMOD_SYSR_ERASE_ON); - - if (SECUMOD_SYSR_ERASE_DONE == (sysr & SECUMOD_SYSR_ERASE_DONE)) { - /* Clear the flag ERASE_DONE */ - SECUMOD->SECUMOD_SYSR = SECUMOD_SYSR_ERASE_DONE; - if (SECD0.config->erased_callback != NULL) - SECD0.config->erased_callback(&SECD0); - } - - /* wait at least one slow clock */ - chSysPolledDelayX(SAMA_PCK / SAMA_SLOW_CLK); - - /* Clear RAM access violation flags */ - SECUMOD->SECUMOD_RAMACCSR = ramaccsr; - /* Clear corresponding alarm flag bit */ - SECUMOD->SECUMOD_SCR = sr; - - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief SECUMOD interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_SECUMOD_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - uint32_t sr, nimpr; - - /* Read alarm status */ - sr = SECUMOD->SECUMOD_SR; - nimpr = SECUMOD->SECUMOD_NIMPR; - - if ((sr & SECUMOD_SR_SHLDM) && (nimpr & SECUMOD_NIMPR_SHLDM)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_SHLDM); - } - else if ((sr & SECUMOD_SR_DBLFM) && (nimpr & SECUMOD_NIMPR_DBLFM)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_DBLFM); - } - else if ((sr & SECUMOD_SR_TST) && (nimpr & SECUMOD_NIMPR_TST)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_TST); - } - else if ((sr & SECUMOD_SR_JTAG) && (nimpr & SECUMOD_NIMPR_JTAG)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_JTAG); - } - else if ((sr & SECUMOD_SR_MCKM) && (nimpr & SECUMOD_NIMPR_MCKM)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_MCKM); - } - else if ((sr & SECUMOD_SR_TPML) && (nimpr & SECUMOD_NIMPR_TPML)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_TPML); - } - else if ((sr & SECUMOD_SR_TPMH) && (nimpr & SECUMOD_NIMPR_TPMH)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_TPMH); - } - else if ((sr & SECUMOD_SR_VDDBUL) && (nimpr & SECUMOD_NIMPR_VDDBUL)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_VDDBUL); - } - else if ((sr & SECUMOD_SR_VDDBUH) && (nimpr & SECUMOD_NIMPR_VDDBUH)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_VDDBUH); - } - else if ((sr & SECUMOD_SR_VDDCOREL) && (nimpr & SECUMOD_NIMPR_VDDCOREL)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_VDDCOREL); - } - else if ((sr & SECUMOD_SR_VDDCOREH) && (nimpr & SECUMOD_NIMPR_VDDCOREH)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_VDDCOREH); - } - else if ((sr & SECUMOD_SR_DET0) && (nimpr & SECUMOD_NIMPR_DET0)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU0); - } - else if ((sr & SECUMOD_SR_DET1) && (nimpr & SECUMOD_NIMPR_DET1)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU1); - } - else if ((sr & SECUMOD_SR_DET2) && (nimpr & SECUMOD_NIMPR_DET2)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU2); - } - else if ((sr & SECUMOD_SR_DET3) && (nimpr & SECUMOD_NIMPR_DET3)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU3); - } - else if ((sr & SECUMOD_SR_DET4) && (nimpr & SECUMOD_NIMPR_DET4)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU4); - } - else if ((sr & SECUMOD_SR_DET5) && (nimpr & SECUMOD_NIMPR_DET5)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU5); - } - else if ((sr & SECUMOD_SR_DET6) && (nimpr & SECUMOD_NIMPR_DET6)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU6); - } - else if ((sr & SECUMOD_SR_DET7) && (nimpr & SECUMOD_NIMPR_DET7)) { - SECD0.secumod_callback(&SECD0, SEC_EVENT_PIOBU7); - } - else { - (void) 0; - } - - /* wait at least one slow clock */ - chSysPolledDelayX(SAMA_PCK / SAMA_SLOW_CLK); - - /* Clear corresponding alarm flag bit */ - SECUMOD->SECUMOD_SCR = sr; - - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Configures PIOBU pads according to configuration struct. - * - * @param[in] listp pointer to a PIOBUConfig array - * @param[in] length length of array - * - * @notapi - */ -void piobu_config(PIOBUConfig *listp, size_t length) { - uint8_t i; - uint32_t cfg; - uint32_t index; - PIOBUConfig *piobup; - - for (i = 0; i < length; i++) { - index = listp[i].pinIndex; - piobup = &listp[i]; - - /* AFV and RFV fields must be set to 0 when dynamic intrusion is selected. */ - if (piobup->dynamic) { - cfg = 0; - } else { - cfg = (piobup->afv << SECUMOD_PIOBU_AFV_Pos ) | (piobup->rfv << SECUMOD_PIOBU_RFV_Pos); - } - - if (piobup->mode) { - cfg |= SECUMOD_PIOBU_OUTPUT; - if (piobup->outputLevel) - cfg |= SECUMOD_PIOBU_PIO_SOD; - } - - cfg |= piobup->pullUpState << SECUMOD_PIOBU_PULLUP_Pos; - - if (piobup->scheduled) - cfg |= SECUMOD_PIOBU_SCHEDULE; - - if (piobup->inputDefaultLevel) - cfg |= SECUMOD_PIOBU_SWITCH; - - /* FILTER3_5 and DYNSTAT fields exist only for even PIOBUs */ - if (0 == (index & 0x01)) { - if (piobup->dynamic) - cfg |= SECUMOD_PIOBU_DYNSTAT; - - if (piobup->filter3_5) - cfg |= SECUMOD_PIOBU_FILTER3_5; - } - SECUMOD->SECUMOD_PIOBU[index] = cfg; - } -} - -/** - * @brief Low level SEC driver initialization. - * - * @notapi - */ -void sec_lld_init(void) { - - /* Driver initialization.*/ - secObjectInit(&SECD0); - SECD0.sec = SECUMOD; -} - -/** - * @brief Configures and activates the SEC peripheral. - * - * @param[in] secp pointer to the @p SECDriver object - * - * @notapi - */ -void sec_lld_start(SECDriver *secp) { - - uint8_t i; - - if (secp->state == SEC_STOP) { - /* Clock activation. */ - pmcEnableSEC(); - - /* Register Reset */ - secp->sec->SECUMOD_NIDPR = SECUMOD_NIDPR_ALL; - secumodSetNormalModeProtections(~SECUMOD_NMPR_ALL); - - /* - * Configure interrupts - */ - aicSetIntSourceType(ID_SECUMOD, INT_LEVEL_SENSITIVE); - aicSetSourcePriority(ID_SECUMOD, SAMA_SECUMOD_IRQ_PRIORITY); - aicSetSourceHandler(ID_SECUMOD, SAMA_SECUMOD_HANDLER); - - aicSetIntSourceType(ID_SECURAM, INT_LEVEL_SENSITIVE); - aicSetSourcePriority(ID_SECURAM, SAMA_SECURAM_IRQ_PRIORITY); - aicSetSourceHandler(ID_SECURAM, SAMA_SECURAM_HANDLER); - - /* Enabling interrupt. */ - aicEnableInt(ID_SECUMOD); - aicEnableInt(ID_SECURAM); - } - - uint32_t ramacc_cfg = 0; - - /* Select mode normal or backup*/ - secp->sec->SECUMOD_CR = secp->config->cr; - - /* Configure JTAGCR */ - secp->sec->SECUMOD_JTAGCR = secp->config->jtagcr; - - /* Configure region rights. */ - for (i = 0; i < SECUMOD_RAM_REGIONS; i++) { - ramacc_cfg |= (secp->config->region[i].mode & 0x3u) << (i * 2); - } - secp->sec->SECUMOD_RAMACC = ramacc_cfg; - - /* Configure PIOBU pads. */ - piobu_config(secp->config->list, secp->config->length); -} - -/** - * @brief Deactivates the SEC peripheral. - * - * @param[in] secp pointer to the @p SECDriver object - * - * @notapi - */ -void sec_lld_stop(SECDriver *secp) { - - secp->sec->SECUMOD_NMPR &= ~(0xFF << 16); - secp->sec->SECUMOD_NIDPR |= (0xFF << 16); - - aicDisableInt(ID_SECURAM); - aicDisableInt(ID_SECUMOD); - - pmcDisableSEC(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ -/** - * @brief SEC Driver initialization. - * - * @init - */ -void secInit(void) { - - sec_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p SECDriver structure. - * - * @param[out] secp pointer to a @p SECDriver object - * - * @init - */ -void secObjectInit(SECDriver *secp) { - - secp->state = SEC_STOP; - secp->config = NULL; -} - -/** - * @brief Configures and activates the SEC peripheral. - * - * @param[in] secp pointer to a @p SECDriver object - * @param[in] config pointer to a @p SECConfig object - * - * @api - */ -void secStart(SECDriver *secp, const SECConfig *config) { - - osalDbgCheck((secp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((secp->state == SEC_STOP), "invalid state"); - secp->config = config; - sec_lld_start(secp); - secp->state = SEC_ACTIVE; - osalSysUnlock(); -} - -/** - * @brief Deactivates the SEC peripheral. - * - * @param[in] secp pointer to a @p SECDriver object - * - * @api - */ -void secStop(SECDriver *secp) { - - osalDbgCheck(secp != NULL); - - osalSysLock(); - - osalDbgAssert((secp->state == SEC_STOP) || (secp->state == SEC_ACTIVE), - "invalid state"); - - sec_lld_stop(secp); - secp->config = NULL; - secp->state = SEC_STOP; - - osalSysUnlock(); -} - -/** - * @brief Enables or disables SECUMOD callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @note The function can be called from any context. - * - * @param[in] secp pointer to SECUMOD driver structure - * @param[in] sources Bitwise OR of protections. - * @param[in] callback callback function pointer or @p NULL - * - * @api - */ -void secSetCallback(SECDriver *secp, uint32_t sources, secumod_callback_t callback) { - - osalDbgCheck(secp != NULL); - - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (callback != NULL) { - - /* IRQ sources enabled only after setting up the callback.*/ - secp->secumod_callback = callback; - secp->sec->SECUMOD_NIEPR = sources; - if (SECUMOD->SECUMOD_NIMPR != sources) { - secumodToggleProtectionReg(); - secp->sec->SECUMOD_NIEPR = sources; - } - } - else { - secp->sec->SECUMOD_NIDPR = sources; - - /* Callback set to NULL only after disabling the IRQ sources.*/ - secp->secumod_callback = NULL; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Set JTAG protection options of SECUMOD. - * - * @param[in] reset Whether preventing debug state and BSD (Boundary Scan Diagnostics) to work. - * @param[in] permissions Debug permissions. - * @param[in] ack Whether monitor the DBGACK signal. - * - * @api - */ -void secumodSetJtagProtection(bool reset, uint8_t permissions, - bool ack) { - - uint32_t jtagcr; - jtagcr = permissions << SECUMOD_JTAGCR_CA5_DEBUG_MODE_Pos; - - if (reset) - jtagcr |= SECUMOD_JTAGCR_FNTRST; - - if (ack) - jtagcr |= SECUMOD_JTAGCR_CA5_DEBUG_MON; - - SECUMOD->SECUMOD_JTAGCR = jtagcr; -} - -/** - * @brief Tuning dynamic signatures by period and threshold. - * - * @param[in] period Signature Clock Period. - * @param[in] detection_thr Error Detection Threshold. - * @param[in] reset_thr Error Counter Reset Threshold. - * - * @api - */ -void secumodDynamicSignaturesTuning(uint16_t period, - uint8_t detectionThr, uint8_t resetThr) { - - uint32_t dystune; - - dystune = SECUMOD->SECUMOD_DYSTUNE & SECUMOD_DYSTUNE_NOPA; - dystune |= SECUMOD_DYSTUNE_PERIOD(period); - dystune |= SECUMOD_DYSTUNE_RX_ERROR_THRESHOLD(detectionThr); - dystune |= SECUMOD_DYSTUNE_RX_OK_CORREL_NUMBER(resetThr); - SECUMOD->SECUMOD_DYSTUNE = dystune; -} - -/** - * @brief Enable/Disable alarm regenerated periodically while intrusion is maintained. - * - * @param[in] enable periodic alarm while intrusion is maintained, - * true: disable, false: enable. - * @api - */ -void secumodPeriodicAlarm(bool enable) { - - uint32_t tmp; - - tmp = SECUMOD->SECUMOD_DYSTUNE & ~SECUMOD_DYSTUNE_NOPA; - if (!enable) - tmp |= SECUMOD_DYSTUNE_NOPA; - SECUMOD->SECUMOD_DYSTUNE = tmp; -} - -/** - * @brief Set access rights for secure RAM in SECUMOD. - * - * @param[in] region RAM region N, - * for N = 0 ~ 5: RAM range (N)Kbyte ~ (N+1)Kbyte; - * for N = 5: register bank 256bit. - * @param rights 0: No access allowed; - * 1: Only write access allowed; - * 2: Only read access allowed; - * 3: Read and write access allowed. - * @api - */ -void secumodSetRamAccessRights(uint32_t region, uint8_t rights) { - - uint32_t tmp; - - tmp = SECUMOD->SECUMOD_RAMACC & ~SECUMOD_RAMACC_RWx_Msk(region); - SECUMOD->SECUMOD_RAMACC = tmp | (rights << SECUMOD_RAMACC_RWx_Pos(region)); -} - -/** - * @brief Read the SECUMOD internal memory from the specified address - * - * @param[in] data Point to where the data read is stored - * @param[in] addr memory address - * @param[in] size The number of bytes to be read - * - * @return Bytes read - * - * @api - */ -uint32_t secumodReadInternalMemory(uint8_t *data, uint32_t addr, uint32_t size) { - - uint32_t i; - uint32_t region; - uint32_t count; - - if (addr >= ((uint32_t)SECURAM)) - addr -= ((uint32_t)SECURAM); - - secumodMemReady(); - - for (i = 0; i < size; i += count) { - region = (addr + i) >> 10; - if ((SECUMOD_RAMACC_RWx_NO_ACCESS(region) == - (SECUMOD->SECUMOD_RAMACC & SECUMOD_RAMACC_RWx_Msk(region))) || - (SECUMOD_RAMACC_RWx_WR_ACCESS(region) == - (SECUMOD->SECUMOD_RAMACC & SECUMOD_RAMACC_RWx_Msk(region)))) { - break; - } - count = size; - if (((region + 1) << 10 ) <= (addr + i + size)) { - size = ((region + 1) << 10) - (addr + i); - } - memcpy(data + i, (uint8_t *)(((uint32_t)SECURAM) + addr + i), count); - } - return i; -} - -/** - * @brief Write data to the SECUMOD internal memory from the specified address - * - * @param[in] data Pointer to the data to be written - * @param[in] addr memory address - * @param[in] size The number of bytes to be be written - * - * @return Bytes written - * - * @api - */ -uint32_t secumodWriteInternalMemory(uint8_t *data, uint32_t addr, uint32_t size) { - - uint32_t i; - uint32_t region; - uint32_t count; - - if (addr >= ((uint32_t)SECURAM)) - addr -= ((uint32_t)SECURAM); - - secumodMemReady(); - - for (i = 0; i < size; i += count) { - region = (addr + i) >> 10; - if ((SECUMOD_RAMACC_RWx_NO_ACCESS(region) == - (SECUMOD->SECUMOD_RAMACC & SECUMOD_RAMACC_RWx_Msk(region))) || - (SECUMOD_RAMACC_RWx_RD_ACCESS(region) == - (SECUMOD->SECUMOD_RAMACC & SECUMOD_RAMACC_RWx_Msk(region)))) { - break; - } - count = size; - if (((region + 1) << 10 ) <= (addr + i + size)) { - size = ((region + 1) << 10) - (addr + i); - } - memcpy((uint8_t *)(((uint32_t)SECURAM) + addr + i), data + i, count); - } - return i; -} - -#endif /* SAMA_USE_SECUMOD */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.h b/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.h deleted file mode 100644 index c5247af89..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_secumod.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_secumod.h - * @brief SAMA SECUMOD support macros and structures. - * - * @addtogroup SAMA5D2x_SECUMOD - * @{ - */ - -#ifndef SAMA_SECUMOD_LLD_H -#define SAMA_SECUMOD_LLD_H - -/** - * @brief Using the SECUMOD driver. - */ -#if !defined(SAMA_USE_SECUMOD) || defined(__DOXYGEN__) -#define SAMA_USE_SECUMOD FALSE -#endif - -#if SAMA_USE_SECUMOD || defined(__DOXYGEN__) - -#include -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ -/** - * @name RAM ACCESS mode macros - * @{ - */ -/** - * @brief No access allowed. - */ -#define RAMACC_NO_ACCESS 0x0U - -/** - * @brief Only write access allowed. - */ -#define RAMACC_WR_ACCESS 0x1U - -/** - * @brief Only read access allowed. - */ -#define RAMACC_RD_ACCESS 0x2U - -/** - * @brief Read and Write access allowed. - */ -#define RAMACC_WR_RD_ACCESS 0x3U -/** @} */ - -/** - * @name SOURCE INTERRUPT macros - * @{ - */ -/* - * @brief Shield Monitor Protection Interrupt Source. - */ -#define SECUMOD_SHLDM (0x1u << 0) - -/* - * @brief Double Frequency Monitor Protection Interrupt Source. - */ -#define SECUMOD_DBLFM (0x1u << 1) - -/* - * @brief Test Pin Protection Interrupt Source. - */ -#define SECUMOD_TST (0x1u << 2) - -/* - * @brief JTAG Pins Protection Interrupt Source. - */ -#define SECUMOD_JTAG (0x1u << 3) - -/* - * @brief Master Clock Monitor Protection Interrupt Source. - */ -#define SECUMOD_MCKM (0x1u << 5) - -/* - * @brief Low Temperature Monitor Protection Interrupt Source. - */ -#define SECUMOD_TPML (0x1u << 6) - -/* - * @brief High Temperature Monitor Protection Interrupt Source. - */ -#define SECUMOD_TPMH (0x1u << 7) - -/* - * @brief Low VDDBU Voltage Monitor Protection Interrupt Source. - */ -#define SECUMOD_VDDBUL (0x1u << 10) - -/* - * @brief High VDDBU Voltage Monitor Protection Interrupt Source. - */ -#define SECUMOD_VDDBUH (0x1u << 11) - -/* - * @brief Low VDDCORE Voltage Monitor Protection Interrupt Source. - */ -#define SECUMOD_VDDCOREL (0x1u << 12) - -/* - * @brief High VDDCORE Voltage Monitor Protection Interrupt Source. - */ -#define SECUMOD_VDDCOREH (0x1u << 13) - -/* - * @brief PIOBUx Intrusion Detector Protection Interrupt Source. - */ -#define SECUMOD_DET0 (0x1u << 16) -#define SECUMOD_DET1 (0x1u << 17) -#define SECUMOD_DET2 (0x1u << 18) -#define SECUMOD_DET3 (0x1u << 19) -#define SECUMOD_DET4 (0x1u << 20) -#define SECUMOD_DET5 (0x1u << 21) -#define SECUMOD_DET6 (0x1u << 22) -#define SECUMOD_DET7 (0x1u << 23) -/** @} */ - -/** - * @name RAM STATUS mode macros - * @{ - */ -/** - * @brief No access violation occurred. - */ -#define RAMACCSR_NO_VIOLATION 0x0U - -/** - * @brief Write access violation occurred. - */ -#define RAMACCSR_WR_VIOLATION 0x1U - -/** - * @brief Read access violation occurred. - */ -#define RAMACCSR_RD_VIOLATION 0x2U - -/** - * @brief Read and Write access violation occurred. - */ -#define RAMACCSR_WR_RD_VIOLATION 0x3U -/** @} */ - -/** - * @name SCRAMB mode macros - * @{ - */ -/** - * @brief SCRAMB ENABLE. - */ -#define SCRAMB_ENABLE 0x1U - -/** - * @brief SCRAMB DISABLE. - */ -#define SCRAMB_DISABLE 0x2U -/** @} */ - -/* - * @brief RAM regions of SECUMOD - */ -#define SECUMOD_RAM_REGIONS 6 - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ -/** - * @name Configuration options - * @{ - */ -/** - * @brief SECUMOD interrupt priority level setting. - */ -#if !defined(SAMA_SECUMOD_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SECUMOD_IRQ_PRIORITY 7 -#endif - -/** - * @brief SECURAM interrupt priority level setting. - */ -#if !defined(SAMA_SECURAM_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_SECURAM_IRQ_PRIORITY 7 -#endif - -/** @} */ -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ -/** - * @brief Driver state machine possible states. - */ -typedef enum { - SEC_UNINIT = 0, /**< Not initialized. */ - SEC_STOP = 1, /**< Stopped. */ - SEC_ACTIVE = 2 /**< Active. */ -} secstate_t; - -/** - * @brief Type of an SECUMOD event. - */ -typedef enum { - SEC_EVENT_SHLDM = 0, /* Triggered on Shield Monitor. */ - SEC_EVENT_DBLFM = 1, /* Triggered on Double Frequency Monitor. */ - SEC_EVENT_TST = 2, /* Triggered on Test Pin Monitor. */ - SEC_EVENT_JTAG = 3, /* Triggered on JTAG Pins Monitor. */ - SEC_EVENT_MCKM = 4, /* Triggered on Master Clock Monitor. */ - SEC_EVENT_TPML = 5, /* Triggered on Low Temperature Monitor. */ - SEC_EVENT_TPMH = 6, /* Triggered on High Temperature Monitor. */ - SEC_EVENT_VDDBUL = 7, /* Triggered on Low VDDBU Voltage Monitor. */ - SEC_EVENT_VDDBUH = 8, /* Triggered on High VDDBU Voltage Monitor. */ - SEC_EVENT_VDDCOREL = 9, /* Triggered on Low VDDCORE Voltage Monitor. */ - SEC_EVENT_VDDCOREH = 10, /* Triggered on High VDDCORE Voltage Monitor. */ - SEC_EVENT_PIOBU0 = 11, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU1 = 12, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU2 = 13, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU3 = 14, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU4 = 15, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU5 = 16, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU6 = 17, /* Triggered on PIOBUx intrusion. */ - SEC_EVENT_PIOBU7 = 18 /* Triggered on PIOBUx intrusion. */ -} secevent_t; - -/** - * @brief Type of a structure representing an SEC driver. - */ -typedef struct SECDriver SECDriver; - -/** - * @brief SECURAM notification callback type. - * - * @param[in] secp pointer to a @p SECDriver object - */ -typedef void (*securam_callback_t)(SECDriver *secp); - -/** - * @brief SECUMOD notification callback type. - * - * @param[in] secp pointer to a @p SECDriver object - */ -typedef void (*secumod_callback_t)(SECDriver *secp, secevent_t event); - -/** - * @brief SECUMOD erase callback type. - * - * @param[in] secp pointer to a @p SECDriver object - */ -typedef void (*erased_callback_t)(SECDriver *secp); - -/** - * @brief Type of RAM access mode. - */ -typedef uint32_t ram_access_mode_t; - -/** - * @brief PIOBU configuration structure. - */ -typedef struct { - /* - * @brief PIOBU pin's index - */ - uint32_t pinIndex:3; - /* - * @brief alarm filter value - */ - uint32_t afv:4; - /* - * @brief reset filter value - */ - uint32_t rfv:4; - /* - * @brief I/O line mode - * @note 0: pure input, 1: enabled in output - */ - uint32_t mode:1; - /* - * @brief Configure the I/O line in output mode - * @note 0: clear, 1: set - */ - uint32_t outputLevel:1; - /* - * @brief programmable pull-up state - * @note 0: none, 1: pull-up; 2: pull-down; 3: reserved - */ - uint32_t pullUpState:2; - /* - * @brief Pull-up/Down Scheduled: - * @note 0: no; 1: yes - */ - uint32_t scheduled:1; - /* - * @brief switch input default state - */ - uint32_t inputDefaultLevel:1; - /* - * @brief Mode of detection intrusion. - * @note 0: static, 1: dynamic - */ - uint32_t dynamic:1; - /* - * @brief filter for dynamic signatures input - * @note 0: 3 stages majority vote, 1: 5 stages - */ - uint32_t filter3_5:1; -} PIOBUConfig; - -typedef struct { - /** - * @brief RAM Access Right - */ - ram_access_mode_t mode; - /* End of the mandatory fields.*/ -} RAMAccessConfig; - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief Callback for memory violation - */ - securam_callback_t securam_callback; - /** - * @brief Callback after memory erasing - */ - erased_callback_t erased_callback; - /** - * @brief lenght of PIOBUConfig array - * @note Number of pads to configure - */ - size_t length; - /** - * @brief pointer to PIOBUConfig array - */ - PIOBUConfig *list; - /** - * @brief RAM Access Rights - */ - RAMAccessConfig region[SECUMOD_RAM_REGIONS]; - /** - * @brief SECUMOD CR register initialization data. - */ - uint32_t cr; - /** - * @brief SECUMOD JTAGCR register initialization data. - */ - uint32_t jtagcr; -} SECConfig; - -/** - * @brief Structure representing a SEC driver. - */ -struct SECDriver { - /** - * @brief Driver state. - */ - secstate_t state; - /** - * @brief Current configuration data. - */ - const SECConfig *config; - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the SECUMOD registers block. - */ - Secumod *sec; - /** - * @brief Callback pointer. - */ - secumod_callback_t secumod_callback; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @brief Switch to Backup Mode. - * - * @api - */ -#define secumodSwitch2BackupMode() { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_BACKUP; \ -} - -/** - * @brief Switch to Normal Mode. - * - * @api - */ -#define secumodSwitch2NormalMode() { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_NORMAL; \ -} - -/** - * @brief Start clear content of SECUMOD internal RAM 4Kbyte and 256bits. - * - * @api - */ -#define secumodSoftwareProtection() { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_SWPROT; \ -} - -/** - * @brief Enable/Disable Auto-Backup. - * - * @param[in] enable Enable auto-backup if true, disable otherwise. - * - * @api - */ -#define secumodSetAutoBackup(enable) { \ - if (enable) { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_AUTOBKP_AUTO_SWITCH; \ - } \ - else { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_AUTOBKP_SW_SWITCH; \ - } \ -} - -/** - * @brief Enable/Disable Memory Scrambling. - * - * @param[in] enable Enable memory scrambling if true, disable otherwise. - * - * @api - */ -#define secumodSetScrambling(enable) { \ - if (enable) { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_SCRAMB_ENABLE; \ - } \ - else { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_SCRAMB_DISABLE; \ - } \ -} - -/** - * @brief Toggle normal or backup protection registers appear and disappear. - * - * @api - */ -#define secumodToggleProtectionReg() { \ - SECUMOD->SECUMOD_CR = SECUMOD_CR_KEY_TOGGLE; \ -} - -/** - * @brief Set scrambling key for secure RAM in SECUMOD. - * - * @param[in] key Scrambling key. - * - * @api - */ -#define secumodSetScramblingKey(key) { \ - SECUMOD->SECUMOD_SCRKEY = key; \ -} - -/** - * @brief Get scrambling key for secure RAM in SECUMOD. - * - * @return Scrambling key. - * - * @api - */ -#define secumodGetScramblingKey() { \ - SECUMOD->SECUMOD_SCRKEY; \ -} - -/** - * @brief Set protections enabled in backup mode. - * - * @note Make sure registers appears before call this function, to toggle the - * appearance of the registers using secumodToggleProtectionReg(). - * - * @param[in] sources Bitwise OR of protections. - * - * @api - */ -#define secumodSetBackupModeProtections(sources) { \ - SECUMOD->SECUMOD_BMPR = sources; \ - if (SECUMOD->SECUMOD_BMPR != sources) { \ - secumodToggleProtectionReg(); \ - SECUMOD->SECUMOD_BMPR = sources; \ - } \ -} - -/** - * @brief Set protections enabled in normal mode. - * - * @note Make sure registers appears before call this function, to toggle the - * appearance of the registers using secumodToggleProtectionReg(). - * - * @param[in] sources Bitwise OR of protections. - * - * @api - */ -#define secumodSetNormalModeProtections(sources) { \ - SECUMOD->SECUMOD_NMPR = sources; \ - if (SECUMOD->SECUMOD_NMPR != sources) { \ - secumodToggleProtectionReg(); \ - SECUMOD->SECUMOD_NMPR = sources; \ - } \ -} - -/** - * @brief Set protection sources which can cause wake up signal generated. - * - * @param[in] sources Bitwise OR of protection sources. - * - * @api - */ -#define secumodSetWakeupProtections(sources) { \ - SECUMOD->SECUMOD_WKPR = sources; \ -} - -/** - * @brief Wait availability status of memory. - * - * @api - */ -#define secumodMemReady() { \ - while (!(SECUMOD->SECUMOD_RAMRDY & SECUMOD_RAMRDY_READY)); \ -} - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ -extern SECDriver SECD0; - -#ifdef __cplusplus -extern "C" { -#endif - void secInit(void); - void secObjectInit(SECDriver *secp); - void secStart(SECDriver *secp, const SECConfig *config); - void secStop(SECDriver *secp); - void secSetCallback(SECDriver *secp, uint32_t sources, secumod_callback_t callback); - void secumodSetJtagProtection(bool reset, uint8_t permissions, bool ack); - void secumodDynamicSignaturesTuning(uint16_t period, uint8_t detectionThr, uint8_t resetThr); - void secumodPeriodicAlarm(bool enable); - void secumodSetRamAccessRights(uint32_t region, uint8_t rights); - uint32_t secumodReadInternalMemory(uint8_t *data, uint32_t addr, uint32_t size); - uint32_t secumodWriteInternalMemory(uint8_t *data, uint32_t addr, uint32_t size); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_USE_SECUMOD */ - -#endif /* SAMA_SECUMOD_LLD_H */ - -/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.c b/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.c deleted file mode 100644 index 5251efd17..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_tc_lld.c - * @brief SAMA TC support code. - * - * @addtogroup TC - * @{ - */ - -#include "hal.h" - -#if SAMA_USE_TC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local macros. */ -/*===========================================================================*/ - -/** - * @brief Enable write protection on TC registers block. - * - * @param[in] tcp pointer to a TC register block - * - * @notapi - */ -#define tcEnableWP(tcp) { \ - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; \ -} - -/** - * @brief Disable write protection on TC registers block. - * - * @param[in] tcp pointer to a TC register block - * - * @notapi - */ -#define tcDisableWP(tcp) { \ - tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD; \ -} - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief TCD0 driver identifier. - * @note The driver TCD0 allocates the timer TC0 when enabled. - */ -#if SAMA_USE_TC0 || defined(__DOXYGEN__) -TCDriver TCD0; -#endif - -/** - * @brief TCD1 driver identifier. - * @note The driver TCD1 allocates the timer TC1 when enabled. - */ -#if SAMA_USE_TC1 || defined(__DOXYGEN__) -TCDriver TCD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Common IRQ handler. - * @note It is assumed that the various sources are only activated if the - * associated callback pointer is not equal to @p NULL in order to not - * perform an extra check in a potentially critical interrupt handler. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @notapi - */ -void tc_lld_serve_interrupt(TCDriver *tcp) { - uint32_t sr, imr, i; - - for (i = 0; i < TC_CHANNELS; i++) { - sr = tcp->tim->TC_CHANNEL[i].TC_SR; - imr = tcp->tim->TC_CHANNEL[i].TC_IMR; - if (((sr & TC_SR_CPCS) != 0) && ((imr & TC_IMR_CPCS) != 0) && - (tcp->config->channels[i].callback != NULL)) { - tcp->config->channels[i].callback(tcp); - } - } -} -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if SAMA_USE_TC0 || defined(__DOXYGEN__) -#if !defined(SAMA_TC0_SUPPRESS_ISR) -/** - * @brief TC0 interrupt handler. - * @note It is assumed that this interrupt is only activated if the callback - * pointer is not equal to @p NULL in order to not perform an extra - * check in a potentially critical interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_TC0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - tc_lld_serve_interrupt(&TCD0); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(SAMA_TC0_SUPPRESS_ISR) */ -#endif /* SAMA_USE_TC0 */ - -#if SAMA_USE_TC1 || defined(__DOXYGEN__) -#if !defined(SAMA_TC1_SUPPRESS_ISR) -/** - * @brief TC1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(SAMA_TC1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - tc_lld_serve_interrupt(&TCD1); - aicAckInt(); - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(SAMA_TC1_SUPPRESS_ISR) */ -#endif /* SAMA_USE_TC1 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level TC driver initialization. - * - * @notapi - */ -void tc_lld_init(void) { - -#if SAMA_USE_TC0 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TC0, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - tcObjectInit(&TCD0); - TCD0.channels = TC_CHANNELS; - TCD0.tim = TC0; - TCD0.clock = SAMA_TC0CLK; -#endif - -#if SAMA_USE_TC1 -#if SAMA_HAL_IS_SECURE - mtxConfigPeriphSecurity(MATRIX1, ID_TC1, SECURE_PER); -#endif /* SAMA_HAL_IS_SECURE */ - /* Driver initialization.*/ - tcObjectInit(&TCD1); - TCD1.channels = TC_CHANNELS; - TCD1.tim = TC1; - TCD1.clock = SAMA_TC1CLK; -#endif - -} - -/** - * @brief Configures and activates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @notapi - */ -void tc_lld_start(TCDriver *tcp) { - uint32_t rc = 0; - - if (tcp->state == TC_STOP) { - /* Clock activation.*/ -#if SAMA_USE_TC0 - if (&TCD0 == tcp) { - pmcEnableTC0(); -#if !defined(SAMA_TC0_SUPPRESS_ISR) - aicSetSourcePriority(ID_TC0, SAMA_TC0_IRQ_PRIORITY); - aicSetSourceHandler(ID_TC0, SAMA_TC0_HANDLER); - aicEnableInt(ID_TC0); -#endif - } -#endif - -#if SAMA_USE_TC1 - if (&TCD1 == tcp) { - pmcEnableTC1(); -#if !defined(SAMA_TC1_SUPPRESS_ISR) - aicSetSourcePriority(ID_TC1, SAMA_TC1_IRQ_PRIORITY); - aicSetSourceHandler(ID_TC1, SAMA_TC1_HANDLER); - aicEnableInt(ID_TC1); -#endif - } -#endif - } - /* Disable Write Protection */ - tcDisableWP(tcp->tim); - /* Output enables*/ - switch (tcp->config->channels[0].mode & TC_OUTPUT_MASK) { - case TC_OUTPUT_ACTIVE: - rc = (tcp->clock) / (tcp->config->channels[0].frequency); - tcp->tim->TC_CHANNEL[0].TC_EMR = TC_EMR_NODIVCLK; - tcp->tim->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET | - TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC; - - tcp->tim->TC_CHANNEL[0].TC_RC = TC_RC_RC(rc); - tcp->tim->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */ - default: - ; - } - switch (tcp->config->channels[1].mode & TC_OUTPUT_MASK) { - case TC_OUTPUT_ACTIVE: - rc = (tcp->clock) / (tcp->config->channels[1].frequency); - tcp->tim->TC_CHANNEL[1].TC_EMR = TC_EMR_NODIVCLK; - tcp->tim->TC_CHANNEL[1].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET | - TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC; - - tcp->tim->TC_CHANNEL[1].TC_RC = TC_RC_RC(rc); - tcp->tim->TC_CHANNEL[1].TC_SR; /* Clear pending IRQs. */ - default: - ; - } - switch (tcp->config->channels[2].mode & TC_OUTPUT_MASK) { - case TC_OUTPUT_ACTIVE: - rc = (tcp->clock) / (tcp->config->channels[2].frequency); - tcp->tim->TC_CHANNEL[2].TC_EMR = TC_EMR_NODIVCLK; - tcp->tim->TC_CHANNEL[2].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET | - TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC; - - tcp->tim->TC_CHANNEL[2].TC_RC = TC_RC_RC(rc); - tcp->tim->TC_CHANNEL[2].TC_SR; /* Clear pending IRQs. */ - default: - ; - } - /* Enable Write Protection */ - tcEnableWP(tcp->tim); -} - -/** - * @brief Deactivates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @notapi - */ -void tc_lld_stop(TCDriver *tcp) { - - /* If in ready state then disables the TC clock.*/ - if (tcp->state == TC_READY) { -#if SAMA_USE_TC0 - if (&TCD0 == tcp) { - aicDisableInt(ID_TC0); - pmcDisableTC0(); - } -#endif - -#if SAMA_USE_TC1 - if (&TCD1 == tcp) { - aicDisableInt(ID_TC1); - pmcDisableTC1(); - } -#endif - } -} - -/** - * @brief Enables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is active using the specified configuration. - * @note The function has effect at the next cycle start. - * @note Channel notification is not enabled. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * @param[in] width TC pulse width as clock pulses number - * - * @notapi - */ -void tc_lld_enable_channel(TCDriver *tcp, - tcchannel_t channel, - tccnt_t width) { - /* Disable Write Protection */ - tcDisableWP(tcp->tim); - - /* Changing channel duty cycle on the fly.*/ - uint32_t rc = tcp->tim->TC_CHANNEL[channel].TC_RC; - tcp->tim->TC_CHANNEL[channel].TC_RA = TC_RA_RA((100 - width) * rc / 100); - tcp->tim->TC_CHANNEL[channel].TC_CCR = TC_CCR_CLKEN; - tcp->tim->TC_CHANNEL[channel].TC_CCR = TC_CCR_SWTRG; - - /* Enable Write Protection */ - tcEnableWP(tcp->tim); -} - -/** - * @brief Disables a TC channel and its notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is disabled and its output line returned to the - * idle state. - * @note The function has effect at the next cycle start. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @notapi - */ -void tc_lld_disable_channel(TCDriver *tcp, tcchannel_t channel) { - - tcp->tim->TC_CHANNEL[channel].TC_CCR = TC_CCR_CLKDIS; -} - -/** - * @brief Enables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already enabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @notapi - */ -void tc_lld_enable_channel_notification(TCDriver *tcp, - tcchannel_t channel) { - tcp->tim->TC_CHANNEL[channel].TC_IER |= TC_IER_CPCS; -} - -/** - * @brief Disables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already disabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @notapi - */ -void tc_lld_disable_channel_notification(TCDriver *tcp, - tcchannel_t channel) { - - tcp->tim->TC_CHANNEL[channel].TC_IDR |= TC_IDR_CPCS; -} - -/** - * @brief Changes TC channel's frequency. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel must be enabled using @p tcEnableChannel(). - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - */ - -void tcChangeChannelFrequency(TCDriver *tcp, - tcchannel_t channel,uint32_t frequency) { - tcDisableWP(tcp->tim); - uint32_t rc =(tcp->clock) / (frequency); - tcp->tim->TC_CHANNEL[channel].TC_RC = TC_RC_RC(rc); - tcEnableWP(tcp->tim); -} -/** - * @brief TC Driver initialization. - * - * @init - */ -void tcInit(void) { - - tc_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p TCDriver structure. - * - * @param[out] tcp pointer to a @p TCDriver object - * - * @init - */ -void tcObjectInit(TCDriver *tcp) { - - tcp->state = TC_STOP; - tcp->config = NULL; - tcp->enabled = 0; - tcp->channels = 0; -} - - -/** - * @brief Configures and activates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] config pointer to a @p TCConfig object - * - * @api - */ -void tcStart(TCDriver *tcp, const TCConfig *config) { - - osalDbgCheck((tcp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((tcp->state == TC_STOP) || (tcp->state == TC_READY), - "invalid state"); - tcp->config = config; - tc_lld_start(tcp); - tcp->enabled = 0; - tcp->state = TC_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the TC peripheral. - * - * @param[in] tcp pointer to a @p TCDriver object - * - * @api - */ -void tcStop(TCDriver *tcp) { - - osalDbgCheck(tcp != NULL); - - osalSysLock(); - - osalDbgAssert((tcp->state == TC_STOP) || (tcp->state == TC_READY), - "invalid state"); - - tc_lld_stop(tcp); - tcp->enabled = 0; - tcp->config = NULL; - tcp->state = TC_STOP; - - osalSysUnlock(); -} - -/** - * @brief Enables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is active using the specified configuration. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * @param[in] width TC pulse width as clock pulses number - * - * @api - */ -void tcEnableChannel(TCDriver *tcp, - tcchannel_t channel, - tccnt_t width) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - - tcEnableChannelI(tcp, channel, width); - - osalSysUnlock(); -} - -/** - * @brief Disables a TC channel and its notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is disabled and its output line returned to the - * idle state. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @api - */ -void tcDisableChannel(TCDriver *tcp, tcchannel_t channel) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - - tcDisableChannelI(tcp, channel); - - osalSysUnlock(); -} - -/** - * @brief Enables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already enabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @api - */ -void tcEnableChannelNotification(TCDriver *tcp, tcchannel_t channel) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - osalDbgAssert((tcp->enabled & ((tcchnmsk_t)1U << (tcchnmsk_t)channel)) != 0U, - "channel not enabled"); - osalDbgAssert(tcp->config->channels[channel].callback != NULL, - "undefined channel callback"); - - tcEnableChannelNotificationI(tcp, channel); - - osalSysUnlock(); -} - -/** - * @brief Disables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already disabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @api - */ -void tcDisableChannelNotification(TCDriver *tcp, tcchannel_t channel) { - - osalDbgCheck((tcp != NULL) && (channel < tcp->channels)); - - osalSysLock(); - - osalDbgAssert(tcp->state == TC_READY, "not ready"); - osalDbgAssert((tcp->enabled & ((tcchnmsk_t)1U << (tcchnmsk_t)channel)) != 0U, - "channel not enabled"); - osalDbgAssert(tcp->config->channels[channel].callback != NULL, - "undefined channel callback"); - - tcDisableChannelNotificationI(tcp, channel); - - osalSysUnlock(); -} - -#endif /* SAMA_USE_TC */ - -/** @} */ - - - - diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.h b/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.h deleted file mode 100644 index 8cf1a8e1a..000000000 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_tc_lld.h +++ /dev/null @@ -1,364 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - 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 SAMA5D2x/sama_tc_lld.h - * @brief SAMA TC subsystem low level driver header. - * - * @addtogroup TC - * @{ - */ - -#ifndef SAMA_TC_LLD_H -#define SAMA_TC_LLD_H - -/** - * @brief Using the TC driver. - */ -#if !defined(SAMA_USE_TC) || defined(__DOXYGEN__) -#define SAMA_USE_TC FALSE -#endif - -#if SAMA_USE_TC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Number of TC channels per TC driver. - */ -#define TC_CHANNELS TCCHANNEL_NUMBER - -/** - * @name TC output mode macros - * @{ - */ -/** - * @brief Standard output modes mask. - */ -#define TC_OUTPUT_MASK 0x0FU - -/** - * @brief Output not driven, callback only. - */ -#define TC_OUTPUT_DISABLED 0x00U - -/** - * @brief Output active. - */ -#define TC_OUTPUT_ACTIVE 0x01U - -/** @} */ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Driver state machine possible states. - */ -typedef enum { - TC_UNINIT = 0, /**< Not initialized. */ - TC_STOP = 1, /**< Stopped. */ - TC_READY = 2 /**< Ready. */ -} tcstate_t; - -/** - * @brief Type of a structure representing a TC driver. - */ -typedef struct TCDriver TCDriver; - -/** - * @brief Type of a TC notification callback. - * - * @param[in] tcp pointer to a @p TCDriver object - */ -typedef void (*tccallback_t)(TCDriver *tcp); - - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief TCD0 driver enable switch. - * @details If set to @p TRUE the support for TCD0 is included. - * @note The default is @p TRUE. - */ -#if !defined(SAMA_USE_TC0) || defined(__DOXYGEN__) -#define SAMA_USE_TC0 FALSE -#endif - -/** - * @brief TCD1 driver enable switch. - * @details If set to @p TRUE the support for TCD1 is included. - * @note The default is @p TRUE. - */ -#if !defined(SAMA_USE_TC1) || defined(__DOXYGEN__) -#define SAMA_USE_TC1 FALSE -#endif - -/** - * @brief TCD0 interrupt priority level setting. - */ -#if !defined(SAMA_TC0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_TC0_IRQ_PRIORITY 2 -#endif - -/** - * @brief TCD1 interrupt priority level setting. - */ -#if !defined(SAMA_TC1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define SAMA_TC1_IRQ_PRIORITY 2 -#endif - -/** @} */ - -/*===========================================================================*/ -/* Configuration checks. */ -/*===========================================================================*/ - -#if !SAMA_USE_TC0 && !SAMA_USE_TC1 -#error "TC driver activated but no TC peripheral assigned" -#endif - -/* Checks on allocation of TCx units.*/ -#if SAMA_USE_TC0 -#if defined(SAMA_TC0_IS_USED) -#error "TC0 is already used" -#else -#define SAMA_TC0_IS_USED -#endif -#endif - -/* Checks on allocation of TCx units.*/ -#if SAMA_USE_TC1 -#if defined(SAMA_TC1_IS_USED) -#error "TC1 is already used" -#else -#define SAMA_TC1_IS_USED -#endif -#endif -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of a TC mode. - */ -typedef uint32_t tcmode_t; - -/** - * @brief Type of a TC channel. - */ -typedef uint8_t tcchannel_t; - -/** - * @brief Type of a channels mask. - */ -typedef uint32_t tcchnmsk_t; - -/** - * @brief Type of a TC counter. - */ -typedef uint32_t tccnt_t; - -/** - * @brief Type of a TC driver channel configuration structure. - */ -typedef struct { - /** - * @brief Channel active logic level. - */ - tcmode_t mode; - /** - * @brief Timer clock in Hz. - * @note The low level can use assertions in order to catch invalid - * frequency specifications. - */ - uint32_t frequency; - /** - * @brief Channel callback pointer. - * @note This callback is invoked on the channel compare event. If set to - * @p NULL then the callback is disabled. - */ - tccallback_t callback; - /* End of the mandatory fields.*/ -} TCChannelConfig; - -/** - * @brief Type of a TC driver configuration structure. - */ -typedef struct { - /** - * @brief Channels configurations. - */ - TCChannelConfig channels[TC_CHANNELS]; - /* End of the mandatory fields.*/ -} TCConfig; - -/** - * @brief Structure representing a TC driver. - */ -struct TCDriver { - /** - * @brief Driver state. - */ - tcstate_t state; - /** - * @brief Current driver configuration data. - */ - const TCConfig *config; - /** - * @brief Mask of the enabled channels. - */ - tcchnmsk_t enabled; - /** - * @brief Number of channels in this instance. - */ - tcchannel_t channels; - /* End of the mandatory fields.*/ - /** - * @brief Timer base clock. - */ - uint32_t clock; - /** - * @brief Pointer to the TCx registers block. - */ - Tc *tim; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ -/** - * @brief Enables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is active using the specified configuration. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * @param[in] width TC pulse width as clock pulses number - * - * @iclass - */ -#define tcEnableChannelI(tcp, channel, width) do { \ - (tcp)->enabled |= ((tcchnmsk_t)1U << (tcchnmsk_t)(channel)); \ - tc_lld_enable_channel(tcp, channel, width); \ -} while (false) - -/** - * @brief Disables a TC channel. - * @pre The TC unit must have been activated using @p tcStart(). - * @post The channel is disabled and its output line returned to the - * idle state. - * @note Depending on the hardware implementation this function has - * effect starting on the next cycle (recommended implementation) - * or immediately (fallback implementation). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcDisableChannelI(tcp, channel) do { \ - (tcp)->enabled &= ~((tcchnmsk_t)1U << (tcchnmsk_t)(channel)); \ - tc_lld_disable_channel(tcp, channel); \ -} while (false) - -/** - * @brief Returns a TC channel status. - * @pre The TC unit must have been activated using @p tcStart(). - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcIsChannelEnabledI(tcp, channel) \ - (((tcp)->enabled & ((tcchnmsk_t)1U << (tcchnmsk_t)(channel))) != 0U) - -/** - * @brief Enables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already enabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcEnableChannelNotificationI(tcp, channel) \ - tc_lld_enable_channel_notification(tcp, channel) - -/** - * @brief Disables a channel de-activation edge notification. - * @pre The TC unit must have been activated using @p tcStart(). - * @pre The channel must have been activated using @p tcEnableChannel(). - * @note If the notification is already disabled then the call has no effect. - * - * @param[in] tcp pointer to a @p TCDriver object - * @param[in] channel TC channel identifier (0...channels-1) - * - * @iclass - */ -#define tcDisableChannelNotificationI(tcp, channel) \ - tc_lld_disable_channel_notification(tcp, channel) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if SAMA_USE_TC0 && !defined(__DOXYGEN__) -extern TCDriver TCD0; -#endif - -#if SAMA_USE_TC1 && !defined(__DOXYGEN__) -extern TCDriver TCD1; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void tcInit(void); - void tcObjectInit(TCDriver *tcp); - void tcStart(TCDriver *tcp, const TCConfig *config); - void tcStop(TCDriver *tcp); - void tcEnableChannel(TCDriver *tcp, - tcchannel_t channel, - tccnt_t width); - void tcDisableChannel(TCDriver *tcp, tcchannel_t channel); - void tcEnableChannelNotification(TCDriver *tcp, tcchannel_t channel); - void tcDisableChannelNotification(TCDriver *tcp, tcchannel_t channel); - void tcChangeChannelFrequency(TCDriver *tcp, tcchannel_t channel, uint32_t frequency); -#ifdef __cplusplus -} -#endif - -#endif /* SAMA_USE_TC */ - -#endif /* SAMA_TC_LLD_H */ - -/** @} */