From 8ab00df7b4939981dda99222b1528f84560e547c Mon Sep 17 00:00:00 2001 From: PARKJIHOON Date: Mon, 16 Dec 2019 14:10:59 +0800 Subject: [PATCH] Adding Samsung Exynos i S111 target code. Adding a new target of HW development kit using [Samsung Exynos i S111](https://www.samsung.com/semiconductor/minisite/exynos/products/iot/exynos-i-s111/) module to Mbed-OS. This will widen the HW choices of Mbed-OS enabled NB-IoT, GNSS and Security (eFuse, AES, SHA-2, PKA, Secure Storage, Security Sub-System, [PUF](https://en.wikipedia.org/wiki/Physical_unclonable_function)) modules. Target Name: S5JS100 Co-authored-by: Ivan Galkin Co-authored-by: Seokwon Lee Co-authored-by: Zhizhe Zhu Co-authored-by: Xinyi Zhao --- .../targets/TARGET_Samsung/mbedtls_device.h | 39 + .../targets/TARGET_Samsung/sha/sha256_alt.c | 428 ++++++ .../targets/TARGET_Samsung/sha/sha256_alt.h | 177 +++ .../targets/TARGET_Samsung/sha/sha512_alt.c | 468 +++++++ .../targets/TARGET_Samsung/sha/sha512_alt.h | 176 +++ platform/mbed_lib.json | 3 + .../TARGET_SIDK_S5JS100/.mbedignore | 1 + .../TARGET_SIDK_S5JS100/PeripheralNames.h | 124 ++ .../TARGET_SIDK_S5JS100/PinNames.h | 179 +++ .../TARGET_SIDK_S5JS100/PortNames.h | 36 + .../TARGET_SIDK_S5JS100/dcxo_update.cpp | 121 ++ .../TARGET_SIDK_S5JS100/device.h | 25 + .../device/TOOLCHAIN_ARM_STD/sidk_s5js100.sct | 53 + .../TOOLCHAIN_ARM_STD/startup_sidk_s5js100.S | 247 ++++ .../device/TOOLCHAIN_GCC_ARM/sidk_s5js100.ld | 260 ++++ .../TOOLCHAIN_GCC_ARM/startup_sidk_s5js100.S | 285 ++++ .../device/TOOLCHAIN_IAR/sidk_s5js100.icf | 55 + .../device/TOOLCHAIN_IAR/startup_s5js100.S | 254 ++++ .../TARGET_SIDK_S5JS100/device/cmsis.h | 43 + .../TARGET_SIDK_S5JS100/device/cmsis_nvic.h | 26 + .../device/cmsis_nvic_virtual.h | 52 + .../TARGET_SIDK_S5JS100/device/s5js100.h | 651 ++++++++++ .../TARGET_SIDK_S5JS100/device/s5js100_cmu.h | 378 ++++++ .../TARGET_SIDK_S5JS100/device/s5js100_hal.h | 27 + .../device/s5js100_pwrcal.c | 479 +++++++ .../device/s5js100_systemreset.c | 332 +++++ .../TARGET_SIDK_S5JS100/device/s5js100_type.h | 31 + .../TARGET_SIDK_S5JS100/device/s5js100_vclk.h | 88 ++ .../TARGET_SIDK_S5JS100/device/sflash_api.cpp | 490 +++++++ .../TARGET_SIDK_S5JS100/device/sflash_api.h | 226 ++++ .../device/system_core_s5js100.c | 237 ++++ .../device/system_core_s5js100.h | 118 ++ .../device/system_core_version.c | 41 + .../device/system_core_version.h | 45 + .../device/system_s5js100.c | 83 ++ .../device/system_s5js100.h | 56 + .../TARGET_Samsung/TARGET_SIDK_S5JS100/gpio.h | 261 ++++ .../TARGET_SIDK_S5JS100/gpio_api.c | 357 +++++ .../TARGET_SIDK_S5JS100/gpio_irq_api.c | 265 ++++ .../TARGET_SIDK_S5JS100/gpio_object.h | 69 + .../TARGET_SIDK_S5JS100/i2c_api.c | 875 +++++++++++++ .../TARGET_SIDK_S5JS100/i2c_def.h | 175 +++ .../TARGET_SIDK_S5JS100/mbed_main_init.cpp | 40 + .../TARGET_SIDK_S5JS100/mbed_rtx.h | 28 + .../TARGET_SIDK_S5JS100/mbed_sdk_init.c | 45 + .../TARGET_SIDK_S5JS100/modem/exynos_ipc.h | 228 ++++ .../modem/modem_io_device.cpp | 253 ++++ .../modem/modem_io_device.h | 169 +++ .../modem/modem_link_device_shmem.cpp | 809 ++++++++++++ .../modem/modem_link_device_shmem.h | 242 ++++ .../TARGET_SIDK_S5JS100/modem/modem_prj.h | 63 + .../TARGET_SIDK_S5JS100/modem/modem_util.h | 59 + .../modem/s5js100_mbox_ipc.cpp | 329 +++++ .../modem/s5js100_mbox_ipc.h | 74 ++ .../TARGET_SIDK_S5JS100/modem/shmem_save.cpp | 363 ++++++ .../TARGET_SIDK_S5JS100/modem/shmem_save.h | 35 + .../TARGET_SIDK_S5JS100/objects.h | 136 ++ .../TARGET_SIDK_S5JS100/pinmap.c | 33 + .../TARGET_SIDK_S5JS100/port_api.c | 111 ++ .../TARGET_SIDK_S5JS100/rtc_api.c | 73 ++ .../TARGET_SIDK_S5JS100/s5js100_dcxo.cpp | 820 ++++++++++++ .../TARGET_SIDK_S5JS100/s5js100_dcxo.h | 114 ++ .../TARGET_SIDK_S5JS100/s5js100_error.h | 49 + .../TARGET_SIDK_S5JS100/s5js100_pinconfig.h | 294 +++++ .../TARGET_SIDK_S5JS100/s5js100_pmip.c | 331 +++++ .../TARGET_SIDK_S5JS100/s5js100_pmip.h | 80 ++ .../TARGET_SIDK_S5JS100/s5js100_pmusfr.h | 190 +++ .../TARGET_SIDK_S5JS100/s5js100_pwr.c | 1151 +++++++++++++++++ .../TARGET_SIDK_S5JS100/s5js100_pwr.h | 109 ++ .../TARGET_SIDK_S5JS100/s5js100_rtos.h | 43 + .../TARGET_SIDK_S5JS100/s5js100_watchdog.c | 301 +++++ .../TARGET_SIDK_S5JS100/s5js100_watchdog.h | 77 ++ .../TARGET_SIDK_S5JS100/serial_api.c | 314 +++++ .../TARGET_SIDK_S5JS100/serial_dummy_api.c | 120 ++ .../TARGET_SIDK_S5JS100/serial_pl011_api.c | 328 +++++ .../TARGET_SIDK_S5JS100/serial_usi_api.c | 343 +++++ .../TARGET_SIDK_S5JS100/sleep.c | 160 +++ .../TARGET_SIDK_S5JS100/spi_api.c | 553 ++++++++ .../TARGET_SIDK_S5JS100/spi_def.h | 287 ++++ .../TARGET_SIDK_S5JS100/us_ticker.c | 177 +++ .../TARGET_SIDK_S5JS100/us_ticker.h | 46 + .../TARGET_SIDK_S5JS100/watchdog_api.c | 307 +++++ .../security_subsystem/api/trng_api.c | 53 + .../security_subsystem/drivers/mb_cmd_hash.c | 163 +++ .../security_subsystem/drivers/mb_cmd_hash.h | 76 ++ .../security_subsystem/drivers/mb_cmd_rng.c | 167 +++ .../security_subsystem/drivers/mb_cmd_rng.h | 52 + .../drivers/mb_cmd_system.c | 264 ++++ .../drivers/mb_cmd_system.h | 120 ++ .../security_subsystem/drivers/sss_common.h | 159 +++ .../drivers/sss_driver_error.h | 368 ++++++ .../drivers/sss_driver_rng.c | 121 ++ .../drivers/sss_driver_rng.h | 45 + .../drivers/sss_driver_sha2.c | 196 +++ .../drivers/sss_driver_sha2.h | 135 ++ .../drivers/sss_driver_util.c | 679 ++++++++++ .../drivers/sss_driver_util.h | 59 + .../security_subsystem/drivers/sss_map.h | 123 ++ .../security_subsystem/drivers/sss_oid.h | 242 ++++ .../security_subsystem/sss_common.h | 161 +++ targets/targets.json | 20 + tools/export/iar/iar_definitions.json | 4 + 102 files changed, 20827 insertions(+) create mode 100644 features/mbedtls/targets/TARGET_Samsung/mbedtls_device.h create mode 100644 features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.c create mode 100644 features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.h create mode 100644 features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.c create mode 100644 features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/.mbedignore create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PeripheralNames.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PinNames.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PortNames.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/dcxo_update.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device.h create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/sidk_s5js100.sct create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/startup_sidk_s5js100.S create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/sidk_s5js100.ld create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/startup_sidk_s5js100.S create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/sidk_s5js100.icf create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/startup_s5js100.S create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic_virtual.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_cmu.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_hal.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_pwrcal.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_systemreset.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_type.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_vclk.h create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.cpp create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_s5js100.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_s5js100.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio.h create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_irq_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_object.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_def.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_main_init.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_rtx.h create mode 100755 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_sdk_init.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/exynos_ipc.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_prj.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_util.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/objects.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/pinmap.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/port_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/rtc_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.cpp create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_error.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pinconfig.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmusfr.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_rtos.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_dummy_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_pl011_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_usi_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/sleep.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_api.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_def.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.c create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.h create mode 100644 targets/TARGET_Samsung/TARGET_SIDK_S5JS100/watchdog_api.c create mode 100644 targets/TARGET_Samsung/security_subsystem/api/trng_api.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_common.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_error.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.c create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_map.h create mode 100644 targets/TARGET_Samsung/security_subsystem/drivers/sss_oid.h create mode 100644 targets/TARGET_Samsung/security_subsystem/sss_common.h diff --git a/features/mbedtls/targets/TARGET_Samsung/mbedtls_device.h b/features/mbedtls/targets/TARGET_Samsung/mbedtls_device.h new file mode 100644 index 0000000000..e1d60690de --- /dev/null +++ b/features/mbedtls/targets/TARGET_Samsung/mbedtls_device.h @@ -0,0 +1,39 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * 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 MBEDTLS_DEVICE_H +#define MBEDTLS_DEVICE_H + +//#define MBEDTLS_DES_ALT + +//#define MBEDTLS_SHA1_ALT +#define MBEDTLS_SHA256_ALT +#define MBEDTLS_SHA512_ALT + +//#define MBEDTLS_AES_ALT + +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +#endif /* MBEDTLS_DEVICE_H */ diff --git a/features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.c b/features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.c new file mode 100644 index 0000000000..fd00e3ac98 --- /dev/null +++ b/features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.c @@ -0,0 +1,428 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * 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 "mbedtls/sha256.h" +#include "mbedtls/platform_util.h" + +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_SHA256_ALT) +#include "mb_cmd_hash.h" +#define SHA256_VALIDATE_RET(cond) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ) +#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +do { \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} while( 0 ) +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +do { \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} while( 0 ) +#endif + + +#include "string.h" +#include "sss_common.h" +#include "mb_cmd_system.h" + +int mbedtls_sha256_sw_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]); +int mbedtls_sha256_sw_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen); + +void mbedtls_sha256_init(mbedtls_sha256_context *ctx) +{ + memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); +} + +void mbedtls_sha256_free(mbedtls_sha256_context *ctx) +{ + if (ctx == NULL) { + return; + } + memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); +} + +void mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + // Corner case: Destination/source contexts are the same + if (dst == src) { + return; + } + + //SHA256_VALIDATE( dst != NULL ); + //SHA256_VALIDATE( src != NULL ); + + memcpy(dst, src, sizeof(mbedtls_sha256_context)); +} + +/* + * SHA-256 context setup + */ +int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) +{ + SHA256_VALIDATE_RET( ctx != NULL ); + SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); + + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is224 == 0 ) + { //SHA-256 by SSS H/W + ctx->is224 = 0; + /// memset( ctx->sbuf, 0, sizeof( ctx->sbuf ) ); + memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); + } + else + { + /* SHA-224 */ + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + ctx->is224 = is224; + } + + return( 0 ); +} + +/* + * SHA-256 process buffer + */ +int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) +{ + if(ctx->is224){ + mbedtls_sha256_sw_update_ret(ctx, input, ilen); + } + else { + if(ilen > MAX_MB_HASH_BLOCK_BLEN || ctx->totals > MAX_MB_HASH_BLOCK_BLEN) { + // H/W SHA has limitation to seperated API with oversized message. + // fall back to S/W SHA-256 + //memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); + if(ctx->totals == 0) { + ctx->total[0] = 0; + ctx->total[1] = 0; + /* SHA-256 */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + } + ctx->totals += ilen; + mbedtls_sha256_sw_update_ret(ctx, input, ilen); + } else { + // SHA-256 handle by SSS H/W + memcpy(ctx->sbuf + ctx->pstMessage.u32DataByteLen, input, ilen); + ctx->pstMessage.u32DataByteLen += ilen; + } + } + return 0; +} + +/* + * SHA-256 final digest + */ +int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) +{ + if(ctx->is224 || ctx->totals > MAX_MB_HASH_BLOCK_BLEN) + mbedtls_sha256_sw_finish_ret(ctx, output); + else { + int ret = FAIL; + unsigned int object_id; + unsigned int block_byte_len; + + ctx->pstDigest.pu08Data = output; /* assign output buffer */ + + stOCTET_STRING stHASH_Input; + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! assign hash_byte_len to compare returned result from sss_fw after hash operation + object_id = OID_SHA2_256; + block_byte_len = 64; /* meaningless*/ + + //! step 1 : set message length parameter to SSS + ret = mb_hash_init(&ctx->pstMessage, object_id); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 2 : set message block to SSS + ctx->pstMessage.pu08Data = ctx->sbuf; + stHASH_Input.pu08Data = ctx->pstMessage.pu08Data; + stHASH_Input.u32DataByteLen = ctx->pstMessage.u32DataByteLen; + + ret = mb_hash_update(&stHASH_Input, block_byte_len); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + + //! step 3 : get hash result from SSS + ret = mb_hash_final(&stHASH_Input, &ctx->pstDigest); + } + return 0; +} + +static const uint32_t K[] = +{ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, +}; + +#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n)) +#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n)))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) + +#define R(t) \ + ( \ + W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \ + S0(W[(t) - 15]) + W[(t) - 16] \ + ) + +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += temp1; (h) = temp1 + temp2; \ + } while( 0 ) + +int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, + const unsigned char data[64] ) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A[8]; + unsigned int i; + + SHA256_VALIDATE_RET( ctx != NULL ); + SHA256_VALIDATE_RET( (const unsigned char *)data != NULL ); + + for( i = 0; i < 8; i++ ) + A[i] = ctx->state[i]; + +#if defined(MBEDTLS_SHA256_SMALLER) + for( i = 0; i < 64; i++ ) + { + if( i < 16 ) + GET_UINT32_BE( W[i], data, 4 * i ); + else + R( i ); + + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); + + temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; + A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; + } +#else /* MBEDTLS_SHA256_SMALLER */ + for( i = 0; i < 16; i++ ) + GET_UINT32_BE( W[i], data, 4 * i ); + + for( i = 0; i < 16; i += 8 ) + { + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); + P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] ); + P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] ); + P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] ); + P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] ); + P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); + P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); + P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); + } + + for( i = 16; i < 64; i += 8 ) + { + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] ); + P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] ); + P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] ); + P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] ); + P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] ); + P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); + P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); + P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); + } +#endif /* MBEDTLS_SHA256_SMALLER */ + + for( i = 0; i < 8; i++ ) + ctx->state[i] += A[i]; + + return( 0 ); +} + + +int mbedtls_sha256_sw_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) +{ + int ret; + uint32_t used; + uint32_t high, low; + + SHA256_VALIDATE_RET( ctx != NULL ); + SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); + + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->total[0] & 0x3F; + + ctx->buffer[used++] = 0x80; + + if( used <= 56 ) + { + /* Enough room for padding + length in current block */ + memset( ctx->buffer + used, 0, 56 - used ); + } + else + { + /* We'll need an extra block */ + memset( ctx->buffer + used, 0, 64 - used ); + + if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + memset( ctx->buffer, 0, 56 ); + } + + /* + * Add message length + */ + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, ctx->buffer, 56 ); + PUT_UINT32_BE( low, ctx->buffer, 60 ); + + if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + /* + * Output final state + */ + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + PUT_UINT32_BE( ctx->state[5], output, 20 ); + PUT_UINT32_BE( ctx->state[6], output, 24 ); + + if( ctx->is224 == 0 ) + PUT_UINT32_BE( ctx->state[7], output, 28 ); + return 0; +} + +int mbedtls_sha256_sw_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) +{ + //process SW SHA224 + int ret; + size_t fill; + uint32_t left; + + SHA256_VALIDATE_RET( ctx != NULL ); + SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); + + if( ilen == 0 ) + return( 0 ); + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + + if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) + return( ret ); + + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); + + return( 0 ); +} + + + +#endif /* MBEDTLS_SHA256_ALT */ +#endif /* MBEDTLS_SHA256_C */ diff --git a/features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.h b/features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.h new file mode 100644 index 0000000000..efa59f1fe0 --- /dev/null +++ b/features/mbedtls/targets/TARGET_Samsung/sha/sha256_alt.h @@ -0,0 +1,177 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * 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 MBEDTLS_SHA256_ALT_H +#define MBEDTLS_SHA256_ALT_H + +#include "mbedtls/sha256.h" + +#if defined(MBEDTLS_SHA256_ALT) + +#include "sss_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ST_SHA256_BUF_SIZE ((size_t) 256) +struct mbedtls_sha256_context_s; + +/** + * \brief SHA-256 context structure + */ +typedef struct mbedtls_sha256_context_s { + /* for S/W SHA-224 */ + uint32_t total[2]; /*!< The number of Bytes processed. */ + uint32_t state[8]; /*!< The intermediate digest state. */ + unsigned char buffer[64]; /*!< The data block being processed. */ + int is224; /*!< Determines which function to use: + 0: Use SHA-256, or 1: Use SHA-224. */ + + /* for H/W SHA-256 */ + uint32_t totals; + unsigned char sbuf[ST_SHA256_BUF_SIZE]; /*!< ST_SHA256_BLOCK_SIZE buffer to store values so that algorithm is called once the buffer is filled */ + stOCTET_STRING pstMessage; + stOCTET_STRING pstDigest; + +} +mbedtls_sha256_context; + +/** + * \brief Initialize SHA-256 context + * + * \param ctx SHA-256 context to be initialized + */ +void mbedtls_sha256_init( mbedtls_sha256_context *ctx ); + +/** + * \brief Clear SHA-256 context + * + * \param ctx SHA-256 context to be cleared + */ +void mbedtls_sha256_free( mbedtls_sha256_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-256 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha256_clone( mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src ); + +/** + * \brief SHA-256 context setup + * + * \param ctx context to be initialized + * \param is224 0 = use SHA256, 1 = use SHA224 + * + * \returns error code + */ +int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); + +/** + * \brief SHA-256 process buffer + * + * \param ctx SHA-256 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-256 final digest + * + * \param ctx SHA-256 context + * \param output SHA-224/256 checksum result + * + * \returns error code + */ +int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ); + +/* Internal use */ +int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-256 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0. + * + * \param ctx The SHA-256 context to initialize. + * \param is224 Determines which function to use. + *
  • 0: Use SHA-256.
  • + *
  • 1: Use SHA-224.
+ */ +MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, + int is224 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-256 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0. + * + * \param ctx The SHA-256 context to initialize. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-256 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0. + * + * \param ctx The SHA-256 context. + * \param output The SHA-224or SHA-256 checksum result. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, + unsigned char output[32] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-256 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0. + * + * \param ctx The SHA-256 context. + * \param data The buffer holding one block of data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, + const unsigned char data[64] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA256_ALT */ + +#endif /* sha256_alt.h */ diff --git a/features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.c b/features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.c new file mode 100644 index 0000000000..196bb7114b --- /dev/null +++ b/features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.c @@ -0,0 +1,468 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * 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 "mbedtls/sha512.h" +#include "mbedtls/platform_util.h" + + +#if defined(MBEDTLS_SHA512_C) +#if defined(_MSC_VER) || defined(__WATCOMC__) + #define UL64(x) x##ui64 +#else + #define UL64(x) x##ULL +#endif + +#if defined(MBEDTLS_SHA512_ALT) +#include "mb_cmd_hash.h" +#define SHA512_VALIDATE_RET(cond) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA ) +#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) + +/* + * 64-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT64_BE +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} +#endif /* GET_UINT64_BE */ + +#ifndef PUT_UINT64_BE +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 7] = (unsigned char) ( (n) ); \ +} +#endif /* PUT_UINT64_BE */ + +#if defined(MBEDTLS_SHA512_SMALLER) +static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i ) +{ + PUT_UINT64_BE(n, b, i); +} +#else +#define sha512_put_uint64_be PUT_UINT64_BE +#endif /* MBEDTLS_SHA512_SMALLER */ + + + +#include "string.h" +#include "sss_common.h" +#include "mb_cmd_system.h" + +int mbedtls_sha512_sw_finish_ret(mbedtls_sha512_context *ctx, unsigned char output[64]); +int mbedtls_sha512_sw_update_ret(mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen); + +void mbedtls_sha512_init(mbedtls_sha512_context *ctx) +{ + SHA512_VALIDATE( ctx != NULL ); + memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); +} + +void mbedtls_sha512_free(mbedtls_sha512_context *ctx) +{ + if( ctx == NULL ) + return; + + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); +} + +void mbedtls_sha512_clone(mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src) +{ + // Corner case: Destination/source contexts are the same + if (dst == src) { + return; + } + + //SHA256_VALIDATE( dst != NULL ); + //SHA256_VALIDATE( src != NULL ); + + memcpy(dst, src, sizeof(mbedtls_sha512_context)); +} + +/* + * SHA-512 context setup + */ +int mbedtls_sha512_starts_ret(mbedtls_sha512_context *ctx, int is384) +{ + SHA512_VALIDATE_RET( ctx != NULL ); + SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); + memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); + ctx->is384 = is384; + + return( 0 ); +} + +/* + * SHA-512 process buffer + */ +int mbedtls_sha512_update_ret(mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen) +{ + if(ilen > MAX_MB_HASH_BLOCK_BLEN || ctx->totals > MAX_MB_HASH_BLOCK_BLEN) { + // H/W SHA has limitation to seperated API with oversized message. + // fall back to S/W SHA-512 + //memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); + if(ctx->totals == 0) { + ctx->total[0] = 0; + ctx->total[1] = 0; + if( ctx->is384 ) { + /* SHA-384 */ + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + } else { + /* SHA-512 */ + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + } + } + ctx->totals += ilen; + mbedtls_sha512_sw_update_ret(ctx, input, ilen); + } else { + // SHA-256 handle by SSS H/W + memcpy(ctx->sbuf + ctx->pstMessage.u32DataByteLen, input, ilen); + ctx->pstMessage.u32DataByteLen += ilen; + } + return 0; +} + +/* + * SHA-256 final digest + */ +int mbedtls_sha512_finish_ret(mbedtls_sha512_context *ctx, unsigned char output[64]) +{ + if(ctx->totals > MAX_MB_HASH_BLOCK_BLEN) { + mbedtls_sha512_sw_finish_ret(ctx, output); + } else { + int ret = FAIL; + unsigned int object_id; + unsigned int block_byte_len; + + ctx->pstDigest.pu08Data = output; /* assign output buffer */ + + stOCTET_STRING stHASH_Input; + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! assign hash_byte_len to compare returned result from sss_fw after hash operation + if( ctx->is384 == 0 ) + object_id = OID_SHA2_512; + else + object_id = OID_SHA2_384; + + block_byte_len = 64; /* meaningless*/ + + //! step 1 : set message length parameter to SSS + ret = mb_hash_init(&ctx->pstMessage, object_id); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 2 : set message block to SSS + ctx->pstMessage.pu08Data = ctx->sbuf; + stHASH_Input.pu08Data = ctx->pstMessage.pu08Data; + stHASH_Input.u32DataByteLen = ctx->pstMessage.u32DataByteLen; + + ret = mb_hash_update(&stHASH_Input, block_byte_len); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 3 : get hash result from SSS + ret = mb_hash_final(&stHASH_Input, &ctx->pstDigest); + } + return 0; +} + +/* + * Round constants + */ +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; +#define MBEDTLS_SHA512_SMALLER 1 +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ) +{ + int i; + uint64_t temp1, temp2, W[80]; + uint64_t A[8]; + + SHA512_VALIDATE_RET( ctx != NULL ); + SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); + +#define SHR(x,n) ((x) >> (n)) +#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n)))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) + +#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) + +#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) + +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += temp1; (h) = temp1 + temp2; \ + } while( 0 ) + + for( i = 0; i < 8; i++ ) + A[i] = ctx->state[i]; + +#if defined(MBEDTLS_SHA512_SMALLER) + for( i = 0; i < 80; i++ ) + { + if( i < 16 ) + { + GET_UINT64_BE( W[i], data, i << 3 ); + } + else + { + W[i] = S1(W[i - 2]) + W[i - 7] + + S0(W[i - 15]) + W[i - 16]; + } + + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); + + temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; + A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; + } +#else /* MBEDTLS_SHA512_SMALLER */ + for( i = 0; i < 16; i++ ) + { + GET_UINT64_BE( W[i], data, i << 3 ); + } + + for( ; i < 80; i++ ) + { + W[i] = S1(W[i - 2]) + W[i - 7] + + S0(W[i - 15]) + W[i - 16]; + } + + i = 0; + do + { + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++; + P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++; + P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++; + P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++; + P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++; + P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++; + P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++; + P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++; + } + while( i < 80 ); +#endif /* MBEDTLS_SHA512_SMALLER */ + + for( i = 0; i < 8; i++ ) + ctx->state[i] += A[i]; + + return( 0 ); +} + +int mbedtls_sha512_sw_finish_ret( mbedtls_sha512_context *ctx, + unsigned char output[64] ) +{ + int ret; + unsigned used; + uint64_t high, low; + + SHA512_VALIDATE_RET( ctx != NULL ); + SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); + + /* + * Add padding: 0x80 then 0x00 until 16 bytes remain for the length + */ + used = ctx->total[0] & 0x7F; + + ctx->buffer[used++] = 0x80; + + if( used <= 112 ) + { + /* Enough room for padding + length in current block */ + memset( ctx->buffer + used, 0, 112 - used ); + } + else + { + /* We'll need an extra block */ + memset( ctx->buffer + used, 0, 128 - used ); + + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + memset( ctx->buffer, 0, 112 ); + } + + /* + * Add message length + */ + high = ( ctx->total[0] >> 61 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + sha512_put_uint64_be( high, ctx->buffer, 112 ); + sha512_put_uint64_be( low, ctx->buffer, 120 ); + + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + /* + * Output final state + */ + sha512_put_uint64_be( ctx->state[0], output, 0 ); + sha512_put_uint64_be( ctx->state[1], output, 8 ); + sha512_put_uint64_be( ctx->state[2], output, 16 ); + sha512_put_uint64_be( ctx->state[3], output, 24 ); + sha512_put_uint64_be( ctx->state[4], output, 32 ); + sha512_put_uint64_be( ctx->state[5], output, 40 ); + + if( ctx->is384 == 0 ) + { + sha512_put_uint64_be( ctx->state[6], output, 48 ); + sha512_put_uint64_be( ctx->state[7], output, 56 ); + } + + return( 0 ); +} + +int mbedtls_sha512_sw_update_ret(mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen) +{ + int ret; + size_t fill; + unsigned int left; + + SHA512_VALIDATE_RET( ctx != NULL ); + SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); + + if( ilen == 0 ) + return( 0 ); + + left = (unsigned int) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t) ilen; + + if( ctx->total[0] < (uint64_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 128 ) + { + if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) + return( ret ); + + input += 128; + ilen -= 128; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); + + return( 0 ); +} + + + +#endif /* MBEDTLS_SHA512_ALT */ +#endif /* MBEDTLS_SHA512_C */ diff --git a/features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.h b/features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.h new file mode 100644 index 0000000000..3c588f64b2 --- /dev/null +++ b/features/mbedtls/targets/TARGET_Samsung/sha/sha512_alt.h @@ -0,0 +1,176 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * 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 MBEDTLS_SHA512_ALT_H +#define MBEDTLS_SHA512_ALT_H + +#include "mbedtls/sha512.h" + +#if defined(MBEDTLS_SHA512_ALT) + +#include "sss_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ST_SHA512_BUF_SIZE ((size_t) 512) +struct mbedtls_sha512_context_s; + +/** + * \brief SHA-512 context structure + */ +typedef struct mbedtls_sha512_context_s { + /* for S/W SHA-384 */ + uint64_t total[2]; /*!< The number of Bytes processed. */ + uint64_t state[8]; /*!< The intermediate digest state. */ + unsigned char buffer[128]; /*!< The data block being processed. */ + int is384; /*!< Determines which function to use: + 0: Use SHA-512, or 1: Use SHA-384. */ + /* for H/W SHA-512 */ + uint32_t totals; + unsigned char sbuf[ST_SHA512_BUF_SIZE]; /*!< ST_SHA512_BLOCK_SIZE buffer to store values so that algorithm is called once the buffer is filled */ + stOCTET_STRING pstMessage; + stOCTET_STRING pstDigest; + +} +mbedtls_sha512_context; + +/** + * \brief Initialize SHA-512 context + * + * \param ctx SHA-512 context to be initialized + */ +void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); + +/** + * \brief Clear SHA-512 context + * + * \param ctx SHA-512 context to be cleared + */ +void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-512 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha512_clone( mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src ); + +/** + * \brief SHA-512 context setup + * + * \param ctx context to be initialized + * \param is224 0 = use SHA256, 1 = use SHA224 + * + * \returns error code + */ +int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is224 ); + +/** + * \brief SHA-512 process buffer + * + * \param ctx SHA-512 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-512 final digest + * + * \param ctx SHA-512 context + * \param output SHA-224/256 checksum result + * + * \returns error code + */ +int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ); + +/* Internal use */ +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-512 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0. + * + * \param ctx The SHA-512 context to initialize. + * \param is224 Determines which function to use. + *
  • 0: Use SHA-512.
  • + *
  • 1: Use SHA-224.
+ */ +MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, + int is224 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-512 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0. + * + * \param ctx The SHA-512 context to initialize. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-512 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0. + * + * \param ctx The SHA-512 context. + * \param output The SHA-224or SHA-512 checksum result. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, + unsigned char output[64] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-512 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0. + * + * \param ctx The SHA-512 context. + * \param data The buffer holding one block of data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA512_ALT */ + +#endif /* sha512_alt.h */ diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index 8942bf367f..0b36dd2e15 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -238,6 +238,9 @@ "DISCO_F413ZH": { "crash-capture-enabled": true, "fatal-error-auto-reboot-enabled": true + }, + "S5JS100": { + "stdio-baud-rate": 115200 } } } diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/.mbedignore b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/.mbedignore new file mode 100644 index 0000000000..1754786bae --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/.mbedignore @@ -0,0 +1 @@ +serial_api_old.c diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PeripheralNames.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PeripheralNames.h new file mode 100644 index 0000000000..84bf52f353 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PeripheralNames.h @@ -0,0 +1,124 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 : PeriPheralNames.h + * @brief : supported peripheral list header + * @date : June 2019 + * + * @note : List up chip dependent peripherals + * + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" +#include "i2c_def.h" +#include "spi_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)S5JS100_USI0_BASE, + UART_1 = (int)S5JS100_USI1_BASE, + UART_2 = (int)S5JS100_UART0_BASE, + UART_3 = (int)S5JS100_UART1_BASE, + UART_4 = 4, + UART_5 = 5, +} UARTName; + +typedef enum { + I2C_0 = (int)I2C0_BASE, + I2C_1 = (int)I2C1_BASE + +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5 +} ADCName; + +typedef enum { + SPI_0 = (int)SPI0_BASE, + SPI_1 = (int)SPI1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + + +#define _UART_NAME_(a, b) a ## b +#define _UART_NAME(a, b) _UART_NAME_(a, b) + +#ifndef UART_STDIO_PORT +#define STDIO_UART_TX UART_TX0 +#define STDIO_UART_RX UART_RX0 +#define STDIO_UART UART_0 +#else +#define STDIO_UART_TX _UART_NAME(UART_TX, UART_STDIO_PORT) +#define STDIO_UART_RX _UART_NAME(UART_RX, UART_STDIO_PORT) +#define STDIO_UART _UART_NAME(UART_, UART_STDIO_PORT) +#endif + + +/* what are these ports for? */ +//#define MBED_UART0 UART_TX0, UART_RX0 +//#define MBED_UART1 UART_TX1, UART_RX1 +//#define MBED_UARTUSB UART_TX1, UART_RX1 + +//USB UART - what for ??? +#define USBTX UART_TX0 +#define USBRX UART_RX0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PinNames.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PinNames.h new file mode 100644 index 0000000000..cdf5bdce46 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PinNames.h @@ -0,0 +1,179 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" +//#include "gpio.h" +#include "s5js100_pinconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + P00 = 0, + P01, + P02, + P03, + P04, + P05, + P06, + P07, + P08, + P09, + P10, + P11, + P12, + P13, + P14, + P15, + P16, + P17, + P18, + P19, + P20, + P21, + P22, + P23, + P24, + P25, + P26, + P27, + P28, + P29, + P30, + P31, + P32, + P33, + P34, + P35, + P36, + P37, + P38, + P39, + P40, + P41, + P42, + P43, + P44, + P45, + P46, + P47, + P48, + P49, + P50, + P51, + P52, + P53, + P54, + P55, + P56, + P57, + P58, + P59, + P60, + P61, + P62, + P63, + P64, + P65, + P66, + P67, + P68, + P69, + P70, + P71, + P72, + + /* Actually Dummy */ + UART_RX4, + UART_TX4, + UART_RX5, + UART_TX5, + + P05_GPIO = GPIO_GPIO5, + P06_GPIO = GPIO_GPIO6, + + //Uart + UART_RX0 = GPIO_USI0_RXD_CLK_SCL, + UART_TX0 = GPIO_USI0_TXD_MOSI_SDA, + UART_RX1 = GPIO_USI1_RXD_CLK_SCL, + UART_TX1 = GPIO_USI1_TXD_MOSI_SDA, + UART_RX2 = GPIO_UART0_RXD, + UART_TX2 = GPIO_UART0_TXD, + UART_RX3 = GPIO_UART1_RXD, + UART_TX3 = GPIO_UART1_TXD, + + + UART0_RTS = GPIO_USI0_RTSN_MISO_NA, + UART0_CTS = GPIO_USI0_CTSN_CSN_NA, + UART1_RTS = GPIO_USI1_RTSN_MISO_NA, + UART1_CTS = GPIO_USI1_CTSN_CSN_NA, + UART2_CTS = GPIO_UART0_CTSB, + UART2_RTS = GPIO_UART0_RTSB, + UART3_CTS = GPIO_UART1_CTSB, + UART3_RTS = GPIO_UART1_RTSB, + + LED1 = P00, + LED2 = P01, + LED3 = P02, + LED4 = P03, + + /* I2C Pin Names */ + I2C_SDA = (36 << 16 | 2 << 8), + I2C_SCL = (35 << 16 | 2 << 8), + + /* SPI Pin Names */ + SPI0_CLK = ((0 << 0) | (0x0 << 11) | (0x2 << 8) | (33 << 16)), + SPI0_CSN = ((0 << 0) | (0x0 << 11) | (0x2 << 8) | (34 << 16)), + SPI0_MISO = ((0 << 0) | (0x0 << 11) | (0x2 << 8) | (31 << 16)), + SPI0_MOSI = ((0 << 0) | (0x0 << 11) | (0x2 << 8) | (32 << 16)), + + SPI1_CLK = ((0x1 << 0) | (0x0 << 11) | (0x0 << 8) | (12 << 16)), + SPI1_CSN = ((0x1 << 0) | (0x0 << 11) | (0x0 << 8) | (15 << 16)), + SPI1_MISO = ((0x1 << 0) | (0x0 << 11) | (0x0 << 8) | (14 << 16)), + SPI1_MOSI = ((0x1 << 0) | (0x0 << 11) | (0x0 << 8) | (13 << 16)), + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PortNames.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PortNames.h new file mode 100644 index 0000000000..15da5fdcae --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/PortNames.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/dcxo_update.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/dcxo_update.cpp new file mode 100644 index 0000000000..7b4dc23b52 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/dcxo_update.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "mbed.h" +#include "modem_io_device.h" +#include "s5js100_dcxo.h" + +#include "mbed_trace.h" +#define TRACE_GROUP "DCXO" + +#ifndef DCXO_UPDATE_DBG_ON +#define DCXO_UPDATE_DBG_ON 0 +#endif +#define DCXO_UPDATE_DBG if (DCXO_UPDATE_DBG_ON) tr_info + +bool g_enable_ctb_loop = false; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +static ModemIoDevice *dcxo_mio; +static Full_set_table_t *ctb_tbl; + +void dcxo_update_task(mio_buf *buf, void *data) +{ + ModemIoDevice *mio = dcxo_mio; + unsigned short force_ctb; + Nl1cHiu_UpdateInd_t pMsg; + + memcpy(&pMsg, buf->data, sizeof(pMsg)); + free_mio_buf(buf); + + switch (pMsg.header.msgType) { + case DCXO_CTB_FULLSET_UPDATE: + DCXO_UPDATE_DBG("DCXO_CTB_FULLSET_UPDATE"); + /* set ACK */ + if (pMsg.header.response != 0x0) { + DCXO_UPDATE_DBG("CTB FULLSET_UPDATE ack/nck field should be 0x0\n"); + return; + } + + dcxo_ctb_sem_wait(); + memcpy((void *)ctb_tbl, pMsg.payload.setTable, sizeof(Full_set_table_t)*DCXO_TEMPERATURE_RANGE); + dcxo_ctb_sem_release(); + + if (g_enable_ctb_loop != true) { + g_enable_ctb_loop = true; + s5js100_dcxo_start_ctb_loop(ctb_tbl); + } + + /* setting done and response to CP */ + pMsg.header.response = DCXO_RESPONSE_ACK; /* 4B for response */ + break; + + case DCXO_TEMP_REQUEST: + /* response TSU value */ + pMsg.header.response = s5js100_tsu_get_temperature();/* GET TSU to decimal ? */ + pMsg.header.response1 = s5js100_dcxo_get_coarse_tune_value();/* GET CTB at same time */ + DCXO_UPDATE_DBG("DCXO_TEMP_REQUEST temperature(%d) coarse_tune_value(%d)", pMsg.header.response - 50000, pMsg.header.response1); + break; + + case DCXO_CTB_FORCE_REQUEST_FOR_FACTORY_CAL: + DCXO_UPDATE_DBG("DCXO_CTB_FORCE_REQUEST_FOR_FACTORY_CAL"); + /* setting done and response to CP */ + dcxo_ctb_sem_wait(); + force_ctb = pMsg.payload.resolution; /* 2B for force ctb value */ + s5js100_dcxo_set_tune_value((unsigned int)force_ctb, 4096); + dcxo_ctb_sem_release(); + break; + + case DCXO_GET_CTB_REQUEST: + pMsg.header.response = s5js100_dcxo_get_coarse_tune_value(); /* 4B for response */ + DCXO_UPDATE_DBG("DCXO_GET_CTB_REQUEST coarse_tune_value(%d)", pMsg.header.response); + break; + + case DCXO_GET_TSX_INFO_REQUEST: + pMsg.header.response = S5JS100_TSX_TYPE; /* 4B for response */ + DCXO_UPDATE_DBG("DCXO_GET_TSX_INFO_REQUEST TSX_INFO(%d)", pMsg.header.response); + break; + + default: + DCXO_UPDATE_DBG("dcxo msg type wrong..\n"); + return; + } + + if (pMsg.header.msgType != DCXO_CTB_FORCE_REQUEST_FOR_FACTORY_CAL) { + mio->write((char *)(&(pMsg.header)), sizeof(UpdateInd_header_t)); + } +} + +extern "C" { + + void dcxo_init(void) + { + char mio_name[32] = "dcxo"; +// DCXO_UPDATE_DBG("%s:%d\n", __func__, __LINE__); + ctb_tbl = (Full_set_table_t *)malloc(sizeof(Full_set_table_t) * DCXO_TEMPERATURE_RANGE); + + dcxo_mio = getModemIoDeviceByName(mio_name); + dcxo_mio->register_ReadCb(dcxo_update_task, NULL); +// DCXO_UPDATE_DBG("%s:%d\n", __func__, __LINE__); + } + +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device.h new file mode 100644 index 0000000000..aeb10620fc --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_DEVICE_H +#define MBED_DEVICE_H + +#include "objects.h" + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/sidk_s5js100.sct b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/sidk_s5js100.sct new file mode 100755 index 0000000000..72b78c2e75 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/sidk_s5js100.sct @@ -0,0 +1,53 @@ +#! armcc -E +;/**************************************************************************** +; * +; * Copyright 2019 Samsung Electronics All Rights Reserved. +; * +; * 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. +; * +; ****************************************************************************/ + +#define S5JS100_BOOTMEM_BASE (0x00000000) +#define S5JS100_BOOTMEM_END (S5JS100_BOOTMEM_BASE + 0x2000) +#define S5JS100_IRAM_BASE (0x00100000) +#define S5JS100_IRAM_SIZE (0x00080000) +#define S5JS100_IRAM_END (S5JS100_IRAM_BASE + S5JS100_IRAM_SIZE) +#define S5JS100_CODE_BASE (0x406F4000) +#define S5JS100_CODE_SIZE (0x00100000) +#define S5JS100_CODE_END (S5JS100_CODE_BASE + S5JS100_CODE_SIZE) +#define S5JS100_FLASH_BASE (0x40000000) +#define S5JS100_VECTOR_SIZE (0x00000200) + +#ifndef MBED_BOOT_STACK_SIZE +#define MBED_BOOT_STACK_SIZE 0x400 +#endif + +#define Stack_Size MBED_BOOT_STACK_SIZE + +LR_IROM1 S5JS100_CODE_BASE S5JS100_CODE_SIZE { ; XIP region size_region + + ER_IROM1 S5JS100_CODE_BASE S5JS100_CODE_SIZE { ; XIP address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + ;leave VECTOR address empty + ; + RW_IRAM1 (S5JS100_IRAM_BASE+S5JS100_VECTOR_SIZE) (S5JS100_IRAM_SIZE-S5JS100_VECTOR_SIZE-Stack_Size) { ; RW data + .ANY (+RW +ZI) + } + + ARM_LIB_STACK (S5JS100_IRAM_END) EMPTY -Stack_Size { ; stack + } +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/startup_sidk_s5js100.S b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/startup_sidk_s5js100.S new file mode 100755 index 0000000000..125088a36c --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_ARM_STD/startup_sidk_s5js100.S @@ -0,0 +1,247 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit| + +__Vectors DCD |Image$$ARM_LIB_STACK$$ZI$$Limit| ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + /* External interrupts */ + DCD WDT_Handler /* 0:Watchdog Timer Interrupt */ + DCD PMU_APTIMER_Handler /* 1:PMU ATimer wakeup source */ + DCD PMU_ALIVEPAD_Handler /* 2:PMU AlivePad wakeup source */ + DCD PMU_JTAG_Handler /* 3:PMU JTAG wakeup source */ + DCD SSS_SSSINT_Handler /* 4:SSS Secure Interrupt */ + DCD SSS_MB_Handler /* 5:SSS Mailbox Interrupt */ + DCD SSS_KM_Handler /* 6:SSS Key Manager Interrupt */ + DCD DMAC_Handler /* 7:PDMAC Interrupt */ + DCD SDIO_Handler /* 8:SDIO CTRL Interrupt */ + DCD TINT0_Handler /* 9:ATIMER 0 Interrupt */ + DCD TINT1_Handler /* 10:ATIMER 1 Interrupt */ + DCD TINT2_Handler /* 11:ATIMER 2 Interrupt */ + DCD TINT3_Handler /* 12:ATIMER 3 Interrupt */ + DCD TINT4_Handler /* 13:ATIMER 4 Interrupt */ + DCD TINT5_Handler /* 14:ATIMER 5 Interrupt */ + DCD GPIO_INTR0_Handler /* 15:Gpio Group0 Interrupt */ + DCD GPIO_INTR1_Handler /* 16:Gpio Group1 Interrupt */ + DCD GPIO_INTR2_Handler /* 17:Gpio Group2 Interrupt */ + DCD USI0_Handler /* 18:USI 0 Interrupt */ + DCD USI1_Handler /* 19:USI 1 Interrupt */ + DCD SPI_Handler /* 20:SPI Interrupt */ + DCD I2C_Handler /* 21:I2C Interrupt */ + DCD PWM0_Handler /* 22:PWM Port0 Interrupt */ + DCD PWM1_Handler /* 23:PWM Port1 Interrupt */ + DCD PWM2_Handler /* 24:PWM Port2 Interrupt */ + DCD PWM3_Handler /* 25:PWM Port3 Interrupt */ + DCD PWM4_Handler /* 26:PWM Port4 Interrupt */ + DCD PPMU_Handler /* 27:Performance Monitor Interrupt */ + DCD EFUSE_WR_Handler /* 28:Efuse Writer Interrupt */ + DCD CM7_CTT0_Handler /* 29:CM7 CTI0 Interrupt */ + DCD CM7_CTT1_Handler /* 30:CM7 CTI1 Interrupt */ + DCD MB_AP_Handler /* 31:Mailbox AP Interrupt */ + DCD UART0_Handler /* 32:UART0 Interrupt */ + DCD UART1_Handler /* 33:UART1 Interrupt */ + DCD GPADC_Handler /* 34:ADC Interrupt */ + DCD MCPU_WDT_Handler /* 35:MCPU Watchdog Timer Interrupt */ + DCD SSS1_Handler /* 36:SSS1 Host Interrupt */ + DCD SSS2_Handler /* 37:SSS2 Host Interrupt */ + DCD SSS_RESET_Handler /* 38:SSS Reset Interrupt */ + DCD SLEEP_Handler /* 39:SLEEP Counter Interrupt */ + DCD TSU0_Handler /* 40:TSU0 Interrupt */ + DCD TSU1_Handler /* 41:TSU1 Interrupt */ + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR SP, =|Image$$ARM_LIB_STACK$$ZI$$Limit| ;ARMCC should intentionally change stack point? + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + /* External interrupts */ + EXPORT WDT_Handler [WEAK]/* 0:Watchdog Timer Interrupt */ + EXPORT PMU_APTIMER_Handler [WEAK]/* 1:PMU ATimer wakeup source */ + EXPORT PMU_ALIVEPAD_Handler [WEAK]/* 2:PMU AlivePad wakeup source */ + EXPORT PMU_JTAG_Handler [WEAK]/* 3:PMU JTAG wakeup source */ + EXPORT SSS_SSSINT_Handler [WEAK]/* 4:SSS Secure Interrupt */ + EXPORT SSS_MB_Handler [WEAK]/* 5:SSS Mailbox Interrupt */ + EXPORT SSS_KM_Handler [WEAK]/* 6:SSS Key Manager Interrupt */ + EXPORT DMAC_Handler [WEAK]/* 7:PDMAC Interrupt */ + EXPORT SDIO_Handler [WEAK]/* 8:SDIO CTRL Interrupt */ + EXPORT TINT0_Handler [WEAK]/* 9:ATIMER 0 Interrupt */ + EXPORT TINT1_Handler [WEAK]/* 10:ATIMER 1 Interrupt */ + EXPORT TINT2_Handler [WEAK]/* 11:ATIMER 2 Interrupt */ + EXPORT TINT3_Handler [WEAK]/* 12:ATIMER 3 Interrupt */ + EXPORT TINT4_Handler [WEAK]/* 13:ATIMER 4 Interrupt */ + EXPORT TINT5_Handler [WEAK]/* 14:ATIMER 5 Interrupt */ + EXPORT GPIO_INTR0_Handler [WEAK]/* 15:Gpio Group0 Interrupt */ + EXPORT GPIO_INTR1_Handler [WEAK]/* 16:Gpio Group1 Interrupt */ + EXPORT GPIO_INTR2_Handler [WEAK]/* 17:Gpio Group2 Interrupt */ + EXPORT USI0_Handler [WEAK]/* 18:USI 0 Interrupt */ + EXPORT USI1_Handler [WEAK]/* 19:USI 1 Interrupt */ + EXPORT SPI_Handler [WEAK]/* 20:SPI Interrupt */ + EXPORT I2C_Handler [WEAK]/* 21:I2C Interrupt */ + EXPORT PWM0_Handler [WEAK]/* 22:PWM Port0 Interrupt */ + EXPORT PWM1_Handler [WEAK]/* 23:PWM Port1 Interrupt */ + EXPORT PWM2_Handler [WEAK]/* 24:PWM Port2 Interrupt */ + EXPORT PWM3_Handler [WEAK]/* 25:PWM Port3 Interrupt */ + EXPORT PWM4_Handler [WEAK]/* 26:PWM Port4 Interrupt */ + EXPORT PPMU_Handler [WEAK]/* 27:Performance Monitor Interrupt */ + EXPORT EFUSE_WR_Handler [WEAK]/* 28:Efuse Writer Interrupt */ + EXPORT CM7_CTT0_Handler [WEAK]/* 29:CM7 CTI0 Interrupt */ + EXPORT CM7_CTT1_Handler [WEAK]/* 30:CM7 CTI1 Interrupt */ + EXPORT MB_AP_Handler [WEAK]/* 31:Mailbox AP Interrupt */ + EXPORT UART0_Handler [WEAK]/* 32:UART0 Interrupt */ + EXPORT UART1_Handler [WEAK]/* 33:UART1 Interrupt */ + EXPORT GPADC_Handler [WEAK]/* 34:ADC Interrupt */ + EXPORT MCPU_WDT_Handler [WEAK]/* 35:MCPU Watchdog Timer Interrupt */ + EXPORT SSS1_Handler [WEAK]/* 36:SSS1 Host Interrupt */ + EXPORT SSS2_Handler [WEAK]/* 37:SSS2 Host Interrupt */ + EXPORT SSS_RESET_Handler [WEAK]/* 38:SSS Reset Interrupt */ + EXPORT SLEEP_Handler [WEAK]/* 39:SLEEP Counter Interrupt */ + EXPORT TSU0_Handler [WEAK]/* 40:TSU0 Interrupt */ + EXPORT TSU1_Handler [WEAK]/* 41:TSU1 Interrupt */ +WDT_Handler +PMU_APTIMER_Handler +PMU_ALIVEPAD_Handler +PMU_JTAG_Handler +SSS_SSSINT_Handler +SSS_MB_Handler +SSS_KM_Handler +DMAC_Handler +SDIO_Handler +TINT0_Handler +TINT1_Handler +TINT2_Handler +TINT3_Handler +TINT4_Handler +TINT5_Handler +GPIO_INTR0_Handler +GPIO_INTR1_Handler +GPIO_INTR2_Handler +USI0_Handler +USI1_Handler +SPI_Handler +I2C_Handler +PWM0_Handler +PWM1_Handler +PWM2_Handler +PWM3_Handler +PWM4_Handler +PPMU_Handler +EFUSE_WR_Handler +CM7_CTT0_Handler +CM7_CTT1_Handler +MB_AP_Handler +UART0_Handler +UART1_Handler +GPADC_Handler +MCPU_WDT_Handler +SSS1_Handler +SSS2_Handler +SSS_RESET_Handler +SLEEP_Handler +TSU0_Handler +TSU1_Handler + B . + + ENDP + + ALIGN + END + +;************************ (C) COPYRIGHT Samsung electronics *****END OF FILE***** + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/sidk_s5js100.ld b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/sidk_s5js100.ld new file mode 100755 index 0000000000..166c3ee3d9 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/sidk_s5js100.ld @@ -0,0 +1,260 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + +/* + * This file is derivative of CMSIS V5.00 gcc_arm.ld + */ +/* Linker script to configure memory regions. */ + +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x406F4000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 1492K +#endif + +#if !defined(MBED_RAM_START) + #define MBED_RAM_START 0x00100000 +#endif + +#if !defined(MBED_RAM_SIZE) + #define MBED_RAM_SIZE 320K +#endif + + +MEMORY +{ + FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE + RAM (rwx) : ORIGIN = MBED_RAM_START, LENGTH = MBED_RAM_SIZE + VECTORS (rwx) : ORIGIN = 0x00000000, LENGTH = 8K +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +/* Heap 1/4 of ram and stack 1/8 */ +__stack_size__ = 0x0400; +__heap_size__ = 0x4000; + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; + +/* Size of the vector table in SRAM */ +M_VECTOR_RAM_SIZE = 0x140; + +SECTIONS +{ + /* Note: The uVisor expects this section at a fixed location, as specified + by the porting process configuration parameter: FLASH_OFFSET. */ + __UVISOR_TEXT_OFFSET = 0x0; + __UVISOR_TEXT_START = ORIGIN(FLASH) + __UVISOR_TEXT_OFFSET; + .text __UVISOR_TEXT_START : + { + __vector_table = .; + KEEP(*(.vector_table)) + __vector_table_end = .; + . = ALIGN(4); + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .isr_vector : + { + . = ALIGN(4); + _v_start = ABSOLUTE(.); + *(.vector_table) + _v_end = ABSOLUTE(.); + } > VECTORS AT > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + .cordio : + { + *CORDIO_RO_2.1.o + *TRIM_2.1.o + } > FLASH + + .interrupts_ram : + { + . = ALIGN(4); + __VECTOR_RAM__ = .; + __interrupts_ram_start__ = .; /* Create a global symbol at data start */ + . += M_VECTOR_RAM_SIZE; + . = ALIGN(4); + __interrupts_ram_end__ = .; /* Define a global symbol at data end */ + } > RAM + + /* ensure that uvisor bss is at the beginning of memory */ + /* Note: The uVisor expects this section at a fixed location, as specified by + * the porting process configuration parameter: SRAM_OFFSET. */ + __UVISOR_SRAM_OFFSET = 0x140; + __UVISOR_BSS_START = ORIGIN(RAM) + __UVISOR_SRAM_OFFSET; + + .data : + { + PROVIDE(__etext = LOADADDR(.data)); + . = ALIGN(4); + __data_start__ = .; + *(vtable) + *(.data) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE (__fini_array_end = .); + + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM AT > FLASH + + .ramfunc ALIGN(4): { + _sramfuncs = ABSOLUTE(.); + KEEP(*(.ramfunc .ramfunc.*)) + _eramfuncs = ABSOLUTE(.); + } > RAM AT > FLASH + + _framfuncs = LOADADDR(.ramfunc); + + /* From now on you can insert any other SRAM region. */ + + + + + .uninitialized (NOLOAD): + { + . = ALIGN(32); + __uninitialized_start = .; + *(.uninitialized) + KEEP(*(.keep.uninitialized)) + . = ALIGN(32); + __uninitialized_end = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + + } > RAM + + bss_size = __bss_end__ - __bss_start__; + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . = ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE - 0x1000; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + +} /* End of sections */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/startup_sidk_s5js100.S b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/startup_sidk_s5js100.S new file mode 100755 index 0000000000..631a68e2f6 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_GCC_ARM/startup_sidk_s5js100.S @@ -0,0 +1,285 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +;/**************************************************************************** +; * +; * Copyright 2019 Samsung Electronics All Rights Reserved. +; * +; * 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 : startup_sidk_s5js100.S + * @brief : start up code for GCC_ARM + * @date : June 2019 + * + * @note : Add chip dependent isr vectors and register handlers + * + */ + + +/* + * This file is derivative of CMSIS V5.00 startup_ARMCM3.S + */ + .syntax unified + .arch armv7-m + + .section .vector_table,"a",%progbits + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External interrupts */ + .long WDT_Handler /* 0:Watchdog Timer Interrupt */ + .long PMU_APTIMER_Handler /* 1:PMU ATimer wakeup source */ + .long PMU_ALIVEPAD_Handler /* 2:PMU AlivePad wakeup source */ + .long PMU_JTAG_Handler /* 3:PMU JTAG wakeup source */ + .long SSS_SSSINT_Handler /* 4:SSS Secure Interrupt */ + .long SSS_MB_Handler /* 5:SSS Mailbox Interrupt */ + .long SSS_KM_Handler /* 6:SSS Key Manager Interrupt */ + .long DMAC_Handler /* 7:PDMAC Interrupt */ + .long SDIO_Handler /* 8:SDIO CTRL Interrupt */ + .long TINT0_Handler /* 9:ATIMER 0 Interrupt */ + .long TINT1_Handler /* 10:ATIMER 1 Interrupt */ + .long TINT2_Handler /* 11:ATIMER 2 Interrupt */ + .long TINT3_Handler /* 12:ATIMER 3 Interrupt */ + .long TINT4_Handler /* 13:ATIMER 4 Interrupt */ + .long TINT5_Handler /* 14:ATIMER 5 Interrupt */ + .long GPIO_INTR0_Handler /* 15:Gpio Group0 Interrupt */ + .long GPIO_INTR1_Handler /* 16:Gpio Group1 Interrupt */ + .long GPIO_INTR2_Handler /* 17:Gpio Group2 Interrupt */ + .long USI0_Handler /* 18:USI 0 Interrupt */ + .long USI1_Handler /* 19:USI 1 Interrupt */ + .long SPI_Handler /* 20:SPI Interrupt */ + .long I2C_Handler /* 21:I2C Interrupt */ + .long PWM0_Handler /* 22:PWM Port0 Interrupt */ + .long PWM1_Handler /* 23:PWM Port1 Interrupt */ + .long PWM2_Handler /* 24:PWM Port2 Interrupt */ + .long PWM3_Handler /* 25:PWM Port3 Interrupt */ + .long PWM4_Handler /* 26:PWM Port4 Interrupt */ + .long PPMU_Handler /* 27:Performance Monitor Interrupt */ + .long EFUSE_WR_Handler /* 28:Efuse Writer Interrupt */ + .long CM7_CTT0_Handler /* 29:CM7 CTI0 Interrupt */ + .long CM7_CTT1_Handler /* 30:CM7 CTI1 Interrupt */ + .long MB_AP_Handler /* 31:Mailbox AP Interrupt */ + .long UART0_Handler /* 32:UART0 Interrupt */ + .long UART1_Handler /* 33:UART1 Interrupt */ + .long GPADC_Handler /* 34:ADC Interrupt */ + .long MCPU_WDT_Handler /* 35:MCPU Watchdog Timer Interrupt */ + .long SSS1_Handler /* 36:SSS1 Host Interrupt */ + .long SSS2_Handler /* 37:SSS2 Host Interrupt */ + .long SSS_RESET_Handler /* 38:SSS Reset Interrupt */ + .long SLEEP_Handler /* 39:SLEEP Counter Interrupt */ + .long TSU0_Handler /* 40:TSU0 Interrupt */ + .long TSU1_Handler /* 41:TSU1 Interrupt */ + + .size __isr_vector, . - __isr_vector + .section .text.Reset_Handler + .thumb + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + /*b . */ + ldr r0, =SystemInit + blx r0 +/* The call to uvisor_init() happens independently of uVisor being enabled or +* not, so it is conditionally compiled only based on FEATURE_UVISOR. */ +#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) + /* Call uvisor_init() */ + ldr r0, =uvisor_init + blx r0 +#endif /* FEATURE_UVISOR && TARGET_UVISOR_SUPPORTED */ +/* + * Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * _etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .Lflash_to_ram_loop_end + + movs r4, 0 +.Lflash_to_ram_loop: + ldr r0, [r1,r4] + str r0, [r2,r4] + adds r4, 4 + cmp r4, r3 + blt .Lflash_to_ram_loop +.Lflash_to_ram_loop_end: + +/* copy ramfunc from FLASH to RAM */ + ldr r1, =_framfuncs + ldr r2, =_sramfuncs + ldr r3, =_eramfuncs + + subs r3, r2 + ble .Lramfunc_loop_end + + movs r4, 0 +.Lramfunc_loop: + ldr r0, [r1,r4] + str r0, [r2,r4] + adds r4, 4 + cmp r4, r3 + blt .Lramfunc_loop +.Lramfunc_loop_end: + +/* Initialize .bss */ +init_bss: + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + ldr r3, =bss_size + + cmp r3, #0 + beq system_startup + + mov r4, #0 +zero: + strb r4, [r1], #1 + subs r3, r3, #1 + bne zero + +system_startup: + ldr r0, =SystemInit + blx r0 + ldr r0, =_start + bx r0 + .pool + .size Reset_Handler, . - Reset_Handler + + .text +/* + * Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers + */ + .macro def_default_handler handler_name + .align 1 + .thumb_func + .weak \handler_name + .type \handler_name, %function +\handler_name : + nop + nop + nop + nop + nop + nop + b . + b HardFault_Handler + nop + nop + nop + nop + nop + nop + nop + .size \handler_name, . - \handler_name + .endm + + def_default_handler NMI_Handler + def_default_handler HardFault_Handler + def_default_handler MemManage_Handler + def_default_handler BusFault_Handler + def_default_handler UsageFault_Handler + def_default_handler SVC_Handler + def_default_handler DebugMon_Handler + def_default_handler PendSV_Handler + def_default_handler SysTick_Handler + def_default_handler Default_Handler + + .macro def_irq_default_handler handler_name + .weak \handler_name + .set \handler_name, Default_Handler + .endm + + /* External interrupts */ + def_irq_default_handler WDT_Handler /* 0:Watchdog Timer Interrupt */ + def_irq_default_handler PMU_APTIMER_Handler /* 1:PMU ATimer wakeup source */ + def_irq_default_handler PMU_ALIVEPAD_Handler /* 2:PMU AlivePad wakeup source */ + def_irq_default_handler PMU_JTAG_Handler /* 3:PMU JTAG wakeup source */ + def_irq_default_handler SSS_SSSINT_Handler /* 4:SSS Secure Interrupt */ + def_irq_default_handler SSS_MB_Handler /* 5:SSS Mailbox Interrupt */ + def_irq_default_handler SSS_KM_Handler /* 6:SSS Key Manager Interrupt */ + def_irq_default_handler DMAC_Handler /* 7:PDMAC Interrupt */ + def_irq_default_handler SDIO_Handler /* 8:SDIO CTRL Interrupt */ + def_irq_default_handler TINT0_Handler /* 9:ATIMER 0 Interrupt */ + def_irq_default_handler TINT1_Handler /* 10:ATIMER 1 Interrupt */ + def_irq_default_handler TINT2_Handler /* 11:ATIMER 2 Interrupt */ + def_irq_default_handler TINT3_Handler /* 12:ATIMER 3 Interrupt */ + def_irq_default_handler TINT4_Handler /* 13:ATIMER 4 Interrupt */ + def_irq_default_handler TINT5_Handler /* 14:ATIMER 5 Interrupt */ + def_irq_default_handler GPIO_INTR0_Handler /* 15:Gpio Group0 Interrupt */ + def_irq_default_handler GPIO_INTR1_Handler /* 16:Gpio Group1 Interrupt */ + def_irq_default_handler GPIO_INTR2_Handler /* 17:Gpio Group2 Interrupt */ + def_irq_default_handler USI0_Handler /* 18:USI 0 Interrupt */ + def_irq_default_handler USI1_Handler /* 19:USI 1 Interrupt */ + def_irq_default_handler SPI_Handler /* 20:SPI Interrupt */ + def_irq_default_handler I2C_Handler /* 21:I2C Interrupt */ + def_irq_default_handler PWM0_Handler /* 22:PWM Port0 Interrupt */ + def_irq_default_handler PWM1_Handler /* 23:PWM Port1 Interrupt */ + def_irq_default_handler PWM2_Handler /* 24:PWM Port2 Interrupt */ + def_irq_default_handler PWM3_Handler /* 25:PWM Port3 Interrupt */ + def_irq_default_handler PWM4_Handler /* 26:PWM Port4 Interrupt */ + def_irq_default_handler PPMU_Handler /* 27:Performance Monitor Interrupt */ + def_irq_default_handler EFUSE_WR_Handler /* 28:Efuse Writer Interrupt */ + def_irq_default_handler CM7_CTT0_Handler /* 29:CM7 CTI0 Interrupt */ + def_irq_default_handler CM7_CTT1_Handler /* 30:CM7 CTI1 Interrupt */ + def_irq_default_handler MB_AP_Handler /* 31:Mailbox AP Interrupt */ + def_irq_default_handler UART0_Handler /* 32:UART0 Interrupt */ + def_irq_default_handler UART1_Handler /* 33:UART1 Interrupt */ + def_irq_default_handler GPADC_Handler /* 34:ADC Interrupt */ + def_irq_default_handler MCPU_WDT_Handler /* 35:MCPU Watchdog Timer Interrupt */ + def_irq_default_handler SSS1_Handler /* 36:SSS1 Host Interrupt */ + def_irq_default_handler SSS2_Handler /* 37:SSS2 Host Interrupt */ + def_irq_default_handler SSS_RESET_Handler /* 38:SSS Reset Interrupt */ + def_irq_default_handler SLEEP_Handler /* 39:SLEEP Counter Interrupt */ + def_irq_default_handler TSU0_Handler /* 40:TSU0 Interrupt */ + def_irq_default_handler TSU1_Handler /* 41:TSU1 Interrupt */ + + .end diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/sidk_s5js100.icf b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/sidk_s5js100.icf new file mode 100755 index 0000000000..de9da29cc5 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/sidk_s5js100.icf @@ -0,0 +1,55 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + +/* Linker file for the IAR Compiler for ARM */ +/* Specials */ +/* Meory Regions */ +define symbol S5JS100_BOOTMEM_BASE = 0x00000000; +define symbol S5JS100_BOOTMEM_END = S5JS100_BOOTMEM_BASE + 8K; +define symbol S5JS100_IRAM_BASE = 0x00100000; +define symbol S5JS100_IRAM_END = S5JS100_IRAM_BASE + 512K; +define symbol S5JS100_CODE_BASE = 0x406F4000; +define symbol S5JS100_CODE_END = S5JS100_CODE_BASE + 1492K; +define symbol S5JS100_FLASH_BASE = 0x40000000; + +/* Stack Size & Heap Size*/ +if (!isdefinedsymbol(MBED_BOOT_STACK_SIZE)) { + define symbol MBED_BOOT_STACK_SIZE = 0x400; +} + +define symbol CSTACK_SIZE = MBED_BOOT_STACK_SIZE; +define symbol HEAP_SIZE = 0x50000; + +/*Meory regions*/ +define memory mem with size = 4G; +define region VECTOR_REGION = mem:[from S5JS100_BOOTMEM_BASE to S5JS100_BOOTMEM_END]; +define region ROM_REGION = mem:[from S5JS100_CODE_BASE to S5JS100_CODE_END]; +define region IRAM_REGION = mem:[from S5JS100_IRAM_BASE to S5JS100_IRAM_END]; + +define block CSTACK with alignment = 8, size = CSTACK_SIZE { }; +define block HEAP with alignment = 8, size = HEAP_SIZE { }; +define block RW { readwrite }; +define block ZI { zi }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:S5JS100_CODE_BASE { readonly section .intvec}; +/* place at address mem:S5JS100_BOOTMEM_BASE { readwrite section .isr_vector }; */ +place in ROM_REGION { readonly }; +place in IRAM_REGION { block RW, block ZI, block HEAP, block CSTACK}; diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/startup_s5js100.S b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/startup_s5js100.S new file mode 100755 index 0000000000..c719ed1e61 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/TOOLCHAIN_IAR/startup_s5js100.S @@ -0,0 +1,254 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + + + MODULE ?cstartup + SECTION .isr_vector:DATA:NOROOT(3) + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + EXTERN _start + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler + DCD HardFault_Handler + DCD MemManage_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD WDT_Handler /* 0:Watchdog Timer Interrupt */ + DCD PMU_APTIMER_Handler /* 1:PMU ATimer wakeup source */ + DCD PMU_ALIVEPAD_Handler /* 2:PMU AlivePad wakeup source */ + DCD PMU_JTAG_Handler /* 3:PMU JTAG wakeup source */ + DCD SSS_SSSINT_Handler /* 4:SSS Secure Interrupt */ + DCD SSS_MB_Handler /* 5:SSS Mailbox Interrupt */ + DCD SSS_KM_Handler /* 6:SSS Key Manager Interrupt */ + DCD DMAC_Handler /* 7:PDMAC Interrupt */ + DCD SDIO_Handler /* 8:SDIO CTRL Interrupt */ + DCD TINT0_Handler /* 9:ATIMER 0 Interrupt */ + DCD TINT1_Handler /* 10:ATIMER 1 Interrupt */ + DCD TINT2_Handler /* 11:ATIMER 2 Interrupt */ + DCD TINT3_Handler /* 12:ATIMER 3 Interrupt */ + DCD TINT4_Handler /* 13:ATIMER 4 Interrupt */ + DCD TINT5_Handler /* 14:ATIMER 5 Interrupt */ + DCD GPIO_INTR0_Handler /* 15:Gpio Group0 Interrupt */ + DCD GPIO_INTR1_Handler /* 16:Gpio Group1 Interrupt */ + DCD GPIO_INTR2_Handler /* 17:Gpio Group2 Interrupt */ + DCD USI0_Handler /* 18:USI 0 Interrupt */ + DCD USI1_Handler /* 19:USI 1 Interrupt */ + DCD SPI_Handler /* 20:SPI Interrupt */ + DCD I2C_Handler /* 21:I2C Interrupt */ + DCD PWM0_Handler /* 22:PWM Port0 Interrupt */ + DCD PWM1_Handler /* 23:PWM Port1 Interrupt */ + DCD PWM2_Handler /* 24:PWM Port2 Interrupt */ + DCD PWM3_Handler /* 25:PWM Port3 Interrupt */ + DCD PWM4_Handler /* 26:PWM Port4 Interrupt */ + DCD PPMU_Handler /* 27:Performance Monitor Interrupt */ + DCD EFUSE_WR_Handler /* 28:Efuse Writer Interrupt */ + DCD CM7_CTT0_Handler /* 29:CM7 CTI0 Interrupt */ + DCD CM7_CTT1_Handler /* 30:CM7 CTI1 Interrupt */ + DCD MB_AP_Handler /* 31:Mailbox AP Interrupt */ + DCD UART0_Handler /* 32:UART0 Interrupt */ + DCD UART1_Handler /* 33:UART1 Interrupt */ + DCD GPADC_Handler /* 34:ADC Interrupt */ + DCD MCPU_WDT_Handler /* 35:MCPU Watchdog Timer Interrupt */ + DCD SSS1_Handler /* 36:SSS1 Host Interrupt */ + DCD SSS2_Handler /* 37:SSS2 Host Interrupt */ + DCD SSS_RESET_Handler /* 38:SSS Reset Interrupt */ + DCD SLEEP_Handler /* 39:SLEEP Counter Interrupt */ + DCD TSU0_Handler /* 40:TSU0 Interrupt */ + DCD TSU1_Handler /* 41:TSU1 Interrupt */ +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =sfe(CSTACK) + MSR MSP, R0 + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBLIC Default_Handler +Default_Handler + /* External interrupts */ + PUBWEAK WDT_Handler /* 0:Watchdog Timer Interrupt */ + PUBWEAK PMU_APTIMER_Handler /* 1:PMU ATimer wakeup source */ + PUBWEAK PMU_ALIVEPAD_Handler /* 2:PMU AlivePad wakeup source */ + PUBWEAK PMU_JTAG_Handler /* 3:PMU JTAG wakeup source */ + PUBWEAK SSS_SSSINT_Handler /* 4:SSS Secure Interrupt */ + PUBWEAK SSS_MB_Handler /* 5:SSS Mailbox Interrupt */ + PUBWEAK SSS_KM_Handler /* 6:SSS Key Manager Interrupt */ + PUBWEAK DMAC_Handler /* 7:PDMAC Interrupt */ + PUBWEAK SDIO_Handler /* 8:SDIO CTRL Interrupt */ + PUBWEAK TINT0_Handler /* 9:ATIMER 0 Interrupt */ + PUBWEAK TINT1_Handler /* 10:ATIMER 1 Interrupt */ + PUBWEAK TINT2_Handler /* 11:ATIMER 2 Interrupt */ + PUBWEAK TINT3_Handler /* 12:ATIMER 3 Interrupt */ + PUBWEAK TINT4_Handler /* 13:ATIMER 4 Interrupt */ + PUBWEAK TINT5_Handler /* 14:ATIMER 5 Interrupt */ + PUBWEAK GPIO_INTR0_Handler /* 15:Gpio Group0 Interrupt */ + PUBWEAK GPIO_INTR1_Handler /* 16:Gpio Group1 Interrupt */ + PUBWEAK GPIO_INTR2_Handler /* 17:Gpio Group2 Interrupt */ + PUBWEAK USI0_Handler /* 18:USI 0 Interrupt */ + PUBWEAK USI1_Handler /* 19:USI 1 Interrupt */ + PUBWEAK SPI_Handler /* 20:SPI Interrupt */ + PUBWEAK I2C_Handler /* 21:I2C Interrupt */ + PUBWEAK PWM0_Handler /* 22:PWM Port0 Interrupt */ + PUBWEAK PWM1_Handler /* 23:PWM Port1 Interrupt */ + PUBWEAK PWM2_Handler /* 24:PWM Port2 Interrupt */ + PUBWEAK PWM3_Handler /* 25:PWM Port3 Interrupt */ + PUBWEAK PWM4_Handler /* 26:PWM Port4 Interrupt */ + PUBWEAK PPMU_Handler /* 27:Performance Monitor Interrupt */ + PUBWEAK EFUSE_WR_Handler /* 28:Efuse Writer Interrupt */ + PUBWEAK CM7_CTT0_Handler /* 29:CM7 CTI0 Interrupt */ + PUBWEAK CM7_CTT1_Handler /* 30:CM7 CTI1 Interrupt */ + PUBWEAK MB_AP_Handler /* 31:Mailbox AP Interrupt */ + PUBWEAK UART0_Handler /* 32:UART0 Interrupt */ + PUBWEAK UART1_Handler /* 33:UART1 Interrupt */ + PUBWEAK GPADC_Handler /* 34:ADC Interrupt */ + PUBWEAK MCPU_WDT_Handler /* 35:MCPU Watchdog Timer Interrupt */ + PUBWEAK SSS1_Handler /* 36:SSS1 Host Interrupt */ + PUBWEAK SSS2_Handler /* 37:SSS2 Host Interrupt */ + PUBWEAK SSS_RESET_Handler /* 38:SSS Reset Interrupt */ + PUBWEAK SLEEP_Handler /* 39:SLEEP Counter Interrupt */ + PUBWEAK TSU0_Handler /* 40:TSU0 Interrupt */ + PUBWEAK TSU1_Handler /* 41:TSU1 Interrupt */ +WDT_Handler +PMU_APTIMER_Handler +PMU_ALIVEPAD_Handler +PMU_JTAG_Handler +SSS_SSSINT_Handler +SSS_MB_Handler +SSS_KM_Handler +DMAC_Handler +SDIO_Handler +TINT0_Handler +TINT1_Handler +TINT2_Handler +TINT3_Handler +TINT4_Handler +TINT5_Handler +GPIO_INTR0_Handler +GPIO_INTR1_Handler +GPIO_INTR2_Handler +USI0_Handler +USI1_Handler +SPI_Handler +I2C_Handler +PWM0_Handler +PWM1_Handler +PWM2_Handler +PWM3_Handler +PWM4_Handler +PPMU_Handler +EFUSE_WR_Handler +CM7_CTT0_Handler +CM7_CTT1_Handler +MB_AP_Handler +UART0_Handler +UART1_Handler +GPADC_Handler +MCPU_WDT_Handler +SSS1_Handler +SSS2_Handler +SSS_RESET_Handler +SLEEP_Handler +TSU0_Handler +TSU1_Handler + + END diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis.h new file mode 100644 index 0000000000..1ef1992bd5 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis.h @@ -0,0 +1,43 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "s5js100.h" +#include "s5js100_type.h" +#include "s5js100_rtos.h" +/* s5js100 System Core */ +#include "system_s5js100.h" +#include "system_core_s5js100.h" +/* s5js100 System Clock */ +#include "s5js100_cmu.h" +#include "s5js100_vclk.h" +/* Embedded Flash Driver */ +#include "sflash_api.h" +/* s5js100 Power */ +#include "s5js100_pwr.h" +/* NVIC Driver */ +#include "cmsis_nvic.h" +/* System Core Version */ +#include "system_core_version.h" +/* HAL implementation */ +#include "s5js100_hal.h" + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic.h new file mode 100644 index 0000000000..f7e5d936fb --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic.h @@ -0,0 +1,26 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x00000000 //Location of vectors in RAM + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic_virtual.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic_virtual.h new file mode 100644 index 0000000000..3ea37a44f6 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/cmsis_nvic_virtual.h @@ -0,0 +1,52 @@ +#include "cmsis.h" + +#ifndef NVIC_VIRTUAL_H +#define NVIC_VIRTUAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "s5js100_type.h" + +/* NVIC functions */ +#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping +#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping +#define NVIC_EnableIRQ __NVIC_EnableIRQ +#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ +#define NVIC_DisableIRQ __NVIC_DisableIRQ +#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ +#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ +#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +#define NVIC_GetActive __NVIC_GetActive +#define NVIC_SetPriority __NVIC_SetPriority +#define NVIC_GetPriority __NVIC_GetPriority +#define NVIC_SystemReset __NVIC_TFMSystemReset + + +/** + * \brief Overriding the default CMSIS system reset implementation by calling + * secure TFM service. + * + */ +__NO_RETURN __STATIC_INLINE void __NVIC_TFMSystemReset(void) +{ + putreg32(0x1, 0x8301100C); + putreg32(0x1 << 1, 0x82020018); + + putreg32(0x4, 0x83011000); // enable watchdog + putreg32(0x1, 0x83011010); + putreg32(0x1, 0x83011020); + putreg32(327, 0x83011004); //set 10ms to be reset , 1 sec=32768 + putreg32(0xFF, 0x83011008); // force to load value to be reset + + /* Wait for the reset */ + for (;;) { + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100.h new file mode 100644 index 0000000000..9ada732d69 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100.h @@ -0,0 +1,651 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 S5JS100_H +#define S5JS100_H + +#ifdef __cplusplus +extern "C" { +#endif +/* ------------------------- Interrupt Number Definition ------------------------ */ +#define S5JS100_IRQ_FIRST (16) /* Vector number of the first external interrupt */ +typedef enum IRQn { + /* ------------------- Cortex-M7 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /* 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /* 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /* 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /* 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /* 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /* 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /* 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /* 15 System Tick Interrupt */ + /* --------------------- S5JS100 Specific Interrupt Numbers ---------------- */ + S5JS100_IRQ_WDG = 0, + S5JS100_IRQ_PMU_ApTimer = 1, + S5JS100_IRQ_PMU_AlivePad = 2, + S5JS100_IRQ_PMU_JtagInt = 3, + S5JS100_IRQ_SSS_SSSINT = 4, + S5JS100_IRQ_SSS_MBINT = 5, + S5JS100_IRQ_SSS_KMINT = 6, + S5JS100_IRQ_DMACINTR = 7, + S5JS100_IRQ_SDIO_INTREQ_L = 8, + S5JS100_IRQ_TINT0 = 9, + S5JS100_IRQ_TINT1 = 10, + S5JS100_IRQ_TINT2 = 11, + S5JS100_IRQ_TINT3 = 12, + S5JS100_IRQ_TINT4 = 13, + S5JS100_IRQ_TINT5 = 14, + S5JS100_IRQ_GPIO_INTR0 = 15, + S5JS100_IRQ_GPIO_INTR1 = 16, + S5JS100_IRQ_GPIO_INTR2 = 17, + S5JS100_IRQ_USI0 = 18, + S5JS100_IRQ_USI1 = 19, + S5JS100_IRQ_SPI = 20, + S5JS100_IRQ_I2C = 21, + S5JS100_IRQ_PWM_INT0 = 22, + S5JS100_IRQ_PWM_INT1 = 23, + S5JS100_IRQ_PWM_INT2 = 24, + S5JS100_IRQ_PWM_INT3 = 25, + S5JS100_IRQ_PWM_INT4 = 26, + S5JS100_IRQ_PPMU = 27, + S5JS100_IRQ_EFUSE_WR = 28, + S5JS100_IRQ_CM7_CTT_0 = 29, + S5JS100_IRQ_CM7_CTT_1 = 30, + S5JS100_IRQ_MAILBOX_AP_INT = 31, + S5JS100_IRQ_UART0 = 32, + S5JS100_IRQ_UART1 = 33, + S5JS100_IRQ_GPADC = 34, + S5JS100_IRQ_MCPU_WDT = 35, + S5JS100_IRQ_SSS_INT1 = 36, + S5JS100_IRQ_SSS_INT2 = 37, + S5JS100_IRQ_SSS_RESET = 38, + S5JS100_IRQ_SLEEP = 39, + S5JS100_IRQ_TSU0 = 40, + S5JS100_IRQ_TSU1 = 41, +} IRQn_Type; + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M7 Processor and Core Peripherals ------- */ +#define __CM7_REV 0x0201U /* Core revision r2p1 */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __DCACHE_PRESENT 1 /* 32KB d-cache */ +#define __ICACHE_PRESENT 1 /* 32KB I-cache */ + +#define __VTOR_PRESENT 1 /* VTOR present or not */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ + +#include /* Processor and core peripherals */ +#include "system_s5js100.h" /* System Header */ +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#if defined ( __CC_ARM ) +#pragma push +#pragma anon_unions +#elif defined(__ICCARM__) +#pragma language=extended +#elif defined(__GNUC__) +/* anonymous unions are enabled by default */ +#elif defined(__TMS470__) +/* anonymous unions are enabled by default */ +#elif defined(__TASKING__) +#pragma warning 586 +#else +#warning Not supported compiler type +#endif + +/*------------- Universal Asynchronous Receiver Transmitter (USI_UART) -----------*/ +typedef struct { + __IO uint32_t ULCON; /* Offset : 0x000 (R/W) Line Control Register */ + __IO uint32_t UCON; /* Offset: 0x004 (R/W) Control Register */ + __IO uint32_t UFCON; /* Offset: 0x008 (R/W) FIFO Control Register */ + __IO uint32_t UMCON; /* Offset: 0x00C (R/W) Modem Control Register */ + __IO uint32_t UTRSTAT; /* Offset: 0x010 (R/W) Tx/Rx Status Register */ + __IO uint32_t UERSTAT; /* Offset: 0x014 (R) Rx Error Status Register */ + __IO uint32_t UFSTAT; /* Offset: 0x018 (R) FIFO Status Register */ + __IO uint32_t UMSTAT; /* Offset: 0x01C (R) Modem Status Register */ + __IO uint32_t UTXH; /* Offset: 0x020 (W) Transmit Buffer Register */ + __IO uint32_t URXH; /* Offset: 0x024 (R) Receive Buffer Register */ + __IO uint32_t UBRDIV; /* Offset: 0x028 (R/W) Baud Rate Divisor Register */ + __IO uint32_t UFRACVAL; /* Offset: 0x02C (R/W) Divisor Fractional value Register */ + __IO uint32_t UINTP; /* Offset: 0x030 (R/W) Interrupt Pending Register */ + __IO uint32_t UINTS; /* Offset: 0x034 (R) Interrupt Source Register */ + __IO uint32_t UINTM; /* Offset: 0x038 (R/W) Interrupt Mask Register */ + __IO uint32_t RESERVED0[1]; + __IO uint32_t UFTL_CONF; /* Offset: 0x040 (R/W) Filter Configuration Register */ + +} S5JS100_USI_UART_TypeDef; + +/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/ +typedef struct { + __IO uint32_t DR; // 0x0000 + __IO uint32_t SR; // 0x0004 + __IO uint32_t RESERVED0[4]; // 0x008~0x014 + __IO uint32_t FR; // 0x018 + __IO uint32_t RESERVED1; // 0x01c + __IO uint32_t ILPR; // 0x020 + __IO uint32_t IBRD; // 0x024 + __IO uint32_t FBRD; // 0x028 + __IO uint32_t LCRH; // 0x02c + __IO uint32_t CR; // 0x030 + __IO uint32_t IFLS; // 0x034 + __IO uint32_t IMSC; // 0x038 + __IO uint32_t RIS; // 0x03C + __IO uint32_t MIS; // 0x040 + __IO uint32_t ICR; // 0x044 + __IO uint32_t DMACR; // 0x048 + __IO uint32_t MODESEL; // 0x04C +} S5JS100_UART_TypeDef; +/* S5JS100 DATA Register Definitions */ +/* Line Control register ****************************************************/ +#define UART_ULCON_SAMPLING_SHIFT 7 +#define UART_ULCON_SAMPLING_MASK (0x1 << UART_ULCON_SAMPLING_SHIFT) +#define UART_ULCON_SAMPLING_16 (0x0 << UART_ULCON_SAMPLING_SHIFT) +#define UART_ULCON_SAMPLING_8 (0x1 << UART_ULCON_SAMPLING_SHIFT) + +#define UART_ULCON_INFRARED_SHIFT 6 +#define UART_ULCON_INFRARED_MASK (0x1 << UART_ULCON_INFRARED_SHIFT) +#define UART_ULCON_INFRARED_NORMAL (0x0 << UART_ULCON_INFRARED_SHIFT) +#define UART_ULCON_INFRARED_IRTXRX (0x1 << UART_ULCON_INFRARED_SHIFT) + +#define UART_ULCON_PARITY_SHIFT 5 +#define UART_ULCON_PARITY_MASK (0x7 << UART_ULCON_PARITY_SHIFT) +#define UART_ULCON_PARITY_NONE (0x0 << UART_ULCON_PARITY_SHIFT) +#define UART_ULCON_PARITY_ODD (0x4 << UART_ULCON_PARITY_SHIFT) +#define UART_ULCON_PARITY_EVEN (0x5 << UART_ULCON_PARITY_SHIFT) +#define UART_ULCON_PARITY_FORCE1 (0x6 << UART_ULCON_PARITY_SHIFT) +#define UART_ULCON_PARITY_FORCE0 (0x7 << UART_ULCON_PARITY_SHIFT) + +#define UART_ULCON_STOPBITS_SHIFT 2 +#define UART_ULCON_STOPBITS_MASK (0x1 << UART_ULCON_STOPBITS_SHIFT) +#define UART_ULCON_STOPBITS_1BIT (0x0 << UART_ULCON_STOPBITS_SHIFT) +#define UART_ULCON_STOPBITS_2BITS (0x1 << UART_ULCON_STOPBITS_SHIFT) + +#define UART_ULCON_DATABITS_SHIFT 0 +#define UART_ULCON_DATABITS_MASK (0x3 << UART_ULCON_DATABITS_SHIFT) +#define UART_ULCON_DATABITS_5BITS (0x0 << UART_ULCON_DATABITS_SHIFT) +#define UART_ULCON_DATABITS_6BITS (0x1 << UART_ULCON_DATABITS_SHIFT) +#define UART_ULCON_DATABITS_7BITS (0x2 << UART_ULCON_DATABITS_SHIFT) +#define UART_ULCON_DATABITS_8BITS (0x3 << UART_ULCON_DATABITS_SHIFT) + +/* Control register *********************************************************/ +#define UART_UCON_TX_DMA_BURST_SHIFT 20 +#define UART_UCON_TX_DMA_BURST_MASK (0x7 << UART_UCON_TX_DMA_BURST_SHIFT) +#define UART_UCON_TX_DMA_BURST_1BYTE (0x0 << UART_UCON_TX_DMA_BURST_SHIFT) +#define UART_UCON_TX_DMA_BURST_4BYTES (0x1 << UART_UCON_TX_DMA_BURST_SHIFT) +#define UART_UCON_TX_DMA_BURST_8BYTES (0x2 << UART_UCON_TX_DMA_BURST_SHIFT) + +#define UART_UCON_RX_DMA_BURST_SHIFT 16 +#define UART_UCON_RX_DMA_BURST_MASK (0x7 << UART_UCON_RX_DMA_BURST_SHIFT) +#define UART_UCON_RX_DMA_BURST_1BYTE (0x0 << UART_UCON_RX_DMA_BURST_SHIFT) +#define UART_UCON_RX_DMA_BURST_4BYTES (0x1 << UART_UCON_RX_DMA_BURST_SHIFT) +#define UART_UCON_RX_DMA_BURST_8BYTES (0x2 << UART_UCON_RX_DMA_BURST_SHIFT) +#define UART_UCON_RX_DMA_BURST_16BYTES (0x3 << UART_UCON_RX_DMA_BURST_SHIFT) + +#define UART_UCON_RX_TOUT_SHIFT 12 +#define UART_UCON_RX_TOUT_MASK (0x7 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_8FRAMES (0x0 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_16FRAMES (0x1 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_24FRAMES (0x2 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_32FRAMES (0x3 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_40FRAMES (0x4 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_48FRAMES (0x5 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_56FRAMES (0x6 << UART_UCON_RX_TOUT_SHIFT) +#define UART_UCON_RX_TOUT_64FRAMES (0x7 << UART_UCON_RX_TOUT_SHIFT) + +#define UART_UCON_RX_FIFO_EMPTY_SHIFT 11 +#define UART_UCON_RX_FIFO_EMPTY_MASK (0x1 << UART_UCON_RX_FIFO_EMPTY_SHIFT) +#define UART_UCON_RX_FIFO_EMPTY_DISABLE (0x0 << UART_UCON_RX_FIFO_EMPTY_SHIFT) +#define UART_UCON_RX_FIFO_EMPTY_ENABLE (0x1 << UART_UCON_RX_FIFO_EMPTY_SHIFT) + +#define UART_UCON_RX_TOUT_DMAS_SHIFT 10 +#define UART_UCON_RX_TOUT_DMAS_MASK (0x1 << UART_UCON_RX_TOUT_DMAS_SHIFT) +#define UART_UCON_RX_TOUT_DMAS_DISABLE (0x0 << UART_UCON_RX_TOUT_DMAS_SHIFT) +#define UART_UCON_RX_TOUT_DMAS_ENABLE (0x1 << UART_UCON_RX_TOUT_DMAS_SHIFT) + +#define UART_UCON_TX_INTTYPE_SHIFT 9 +#define UART_UCON_TX_INTTYPE_MASK (UART_UCON_TX_INTTYPE_SHIFT) +#define UART_UCON_TX_INTTYPE_PULSE (0x0 << UART_UCON_TX_INTTYPE_SHIFT) +#define UART_UCON_TX_INTTYPE_LEVEL (0x1 << UART_UCON_TX_INTTYPE_SHIFT) + +#define UART_UCON_RX_INTTYPE_SHIFT 8 +#define UART_UCON_RX_INTTYPE_MASK (UART_UCON_RX_INTTYPE_SHIFT) +#define UART_UCON_RX_INTTYPE_PULSE (0x0 << UART_UCON_RX_INTTYPE_SHIFT) +#define UART_UCON_RX_INTTYPE_LEVEL (0x1 << UART_UCON_RX_INTTYPE_SHIFT) + +#define UART_UCON_RX_TOUTINT_SHIFT 7 +#define UART_UCON_RX_TOUTINT_MASK (0x1 << UART_UCON_RX_TOUTINT_SHIFT) +#define UART_UCON_RX_TOUTINT_DISABLE (0x0 << UART_UCON_RX_TOUTINT_SHIFT) +#define UART_UCON_RX_TOUTINT_ENABLE (0x1 << UART_UCON_RX_TOUTINT_SHIFT) + +#define UART_UCON_RX_ERRINT_SHIFT 6 +#define UART_UCON_RX_ERRINT_MASK (0x1 << UART_UCON_RX_ERRINT_SHIFT) +#define UART_UCON_RX_ERRINT_DISABLE (0x0 << UART_UCON_RX_ERRINT_SHIFT) +#define UART_UCON_RX_ERRINT_ENABLE (0x1 << UART_UCON_RX_ERRINT_SHIFT) + +#define UART_UCON_LOOPBACK_SHIFT 5 +#define UART_UCON_LOOPBACK_MASK (0x1 << UART_UCON_LOOPBACK_SHIFT) +#define UART_UCON_LOOPBACK_DISABLE (0x0 << UART_UCON_LOOPBACK_SHIFT) +#define UART_UCON_LOOPBACK_ENABLE (0x1 << UART_UCON_LOOPBACK_SHIFT) + +#define UART_UCON_SEND_BREAK_SHIFT 4 +#define UART_UCON_SEND_BREAK (0x1 << UART_UCON_SEND_BREAK_SHIFT) + +#define UART_UCON_TX_MODE_SHIFT 2 +#define UART_UCON_TX_MODE_MASK (0x3 << UART_UCON_TX_MODE_SHIFT) +#define UART_UCON_TX_MODE_DISABLE (0x0 << UART_UCON_TX_MODE_SHIFT) +#define UART_UCON_TX_MODE_IRQPOLL (0x1 << UART_UCON_TX_MODE_SHIFT) +#define UART_UCON_TX_MODE_DMA (0x2 << UART_UCON_TX_MODE_SHIFT) +#define UART_UCON_TX_MODE_RESERVED (0x3 << UART_UCON_TX_MODE_SHIFT) + +#define UART_UCON_RX_MODE_SHIFT 0 +#define UART_UCON_RX_MODE_MASK (0x3 << UART_UCON_RX_MODE_SHIFT) +#define UART_UCON_RX_MODE_DISABLE (0x0 << UART_UCON_RX_MODE_SHIFT) +#define UART_UCON_RX_MODE_IRQPOLL (0x1 << UART_UCON_RX_MODE_SHIFT) +#define UART_UCON_RX_MODE_DMA (0x2 << UART_UCON_RX_MODE_SHIFT) +#define UART_UCON_RX_MODE_RESERVED (0x3 << UART_UCON_RX_MODE_SHIFT) + +/* FIFO Control register ****************************************************/ +#define UART_UFCON_TX_FIFO_TRIG_SHIFT 8 +#define UART_UFCON_TX_FIFO_TRIG_MASK (0x7 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_0BYTE (0x0 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_2BYTES (0x1 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_4BYTES (0x2 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_6BYTES (0x3 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_8BYTES (0x4 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_10BYTES (0x4 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_12BYTES (0x5 << UART_UFCON_TX_FIFO_TRIG_SHIFT) +#define UART_UFCON_TX_FIFO_TRIG_14BYTES (0x6 << UART_UFCON_TX_FIFO_TRIG_SHIFT) + +#define UART_UFCON_RX_FIFO_TRIG_SHIFT 4 +#define UART_UFCON_RX_FIFO_TRIG_MASK (0x7 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_0BYTE (0x0 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_2BYTES (0x1 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_4BYTES (0x2 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_6BYTES (0x3 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_8BYTES (0x4 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_10BYTES (0x4 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_12BYTES (0x5 << UART_UFCON_RX_FIFO_TRIG_SHIFT) +#define UART_UFCON_RX_FIFO_TRIG_14BYTES (0x6 << UART_UFCON_RX_FIFO_TRIG_SHIFT) + +#define UART_UFCON_TX_FIFO_RESET_SHIFT 2 +#define UART_UFCON_TX_FIFO_RESET (0x1 << UART_UFCON_TX_FIFO_RESET_SHIFT) + +#define UART_UFCON_RX_FIFO_RESET_SHIFT 1 +#define UART_UFCON_RX_FIFO_RESET (0x1 << UART_UFCON_RX_FIFO_RESET_SHIFT) + +#define UART_UFCON_FIFO_SHIFT 0 +#define UART_UFCON_FIFO_MASK (0x1 << UART_UFCON_FIFO_SHIFT) +#define UART_UFCON_FIFO_DISABLE (0x0 << UART_UFCON_FIFO_SHIFT) +#define UART_UFCON_FIFO_ENABLE (0x1 << UART_UFCON_FIFO_SHIFT) + +/* Modem Control register ***************************************************/ +#define UART_UMCON_RTS_TRIG_SHIFT 5 +#define UART_UMCON_RTS_TRIG_MASK (0x7 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_15BYTES (0x0 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_14BYTES (0x1 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_12BYTES (0x2 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_10BYTES (0x3 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_8BYTES (0x4 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_6BYTES (0x5 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_4BYTES (0x6 << UART_UMCON_RTS_TRIG_SHIFT) +#define UART_UMCON_RTS_TRIG_2BYTES (0x7 << UART_UMCON_RTS_TRIG_SHIFT) + +#define UART_UMCON_AFC_SHIFT 4 +#define UART_UMCON_AFC_MASK (0x1 << UART_UMCON_AFC_SHIFT) +#define UART_UMCON_AFC_DISABLE (0x0 << UART_UMCON_AFC_SHIFT) +#define UART_UMCON_AFC_ENABLE (0x1 << UART_UMCON_AFC_SHIFT) + +#define UART_UMCON_MODEM_INT_SHIFT 3 +#define UART_UMCON_MODEM_INT_MASK (0x1 << UART_UMCON_MODEM_INT_SHIFT) +#define UART_UMCON_MODEM_INT_DISABLE (0x0 << UART_UMCON_MODEM_INT_SHIFT) +#define UART_UMCON_MODEM_INT_ENABLE (0x1 << UART_UMCON_MODEM_INT_SHIFT) + +#define UART_UMCON_REQ_TO_SEND_SHIFT 0 +#define UART_UMCON_REQ_TO_SEND_MASK (0x1 << UART_UMCON_REQ_TO_SEND_SHIFT) +#define UART_UMCON_REQ_TO_SEND_HIGH (0x0 << UART_UMCON_REQ_TO_SEND_SHIFT) +#define UART_UMCON_REQ_TO_SEND_LOW (0x1 << UART_UMCON_REQ_TO_SEND_SHIFT) + +/* Tx/Rx Status register ****************************************************/ +#define UART_UTRSTAT_RX_FIFO_CNT_SHIFT 16 +#define UART_UTRSTAT_RX_FIFO_CNT_MASK (0xff << UART_UTRSTAT_RXFIFO_CNT_SHIFT) + +#define UART_UTRSTAT_TX_DMA_SHIFT 12 +#define UART_UTRSTAT_TX_DMA_MASK (0xf << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_IDLE (0x0 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_BURST_REQ (0x1 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_BURST_ACK (0x2 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_BURST_NEXT (0x3 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_SINGLE_REQ (0x4 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_SINGLE_ACK (0x5 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_SINGLE_NEXT (0x6 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_LBURST_REQ (0x7 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_LBURST_ACK (0x8 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_LSINGLE_REQ (0x9 << UART_UTRSTAT_TX_DMA_SHIFT) +#define UART_UTRSTAT_TX_DMA_LSINGLE_ACK (0xa << UART_UTRSTAT_TX_DMA_SHIFT) + +#define UART_UTRSTAT_RX_DMA_SHIFT 8 +#define UART_UTRSTAT_RX_DMA_MASK (0xf << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_IDLE (0x0 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_BURST_REQ (0x1 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_BURST_ACK (0x2 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_BURST_NEXT (0x3 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_SINGLE_REQ (0x4 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_SINGLE_ACK (0x5 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_SINGLE_NEXT (0x6 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_LBURST_REQ (0x7 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_LBURST_ACK (0x8 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_LSINGLE_REQ (0x9 << UART_UTRSTAT_RX_DMA_SHIFT) +#define UART_UTRSTAT_RX_DMA_LSINGLE_ACK (0xa << UART_UTRSTAT_RX_DMA_SHIFT) + +#define UART_UTRSTAT_RX_TOUT_SHIFT 3 +#define UART_UTRSTAT_RX_TOUT_MASK (0x1 << UART_UTRSTAT_RX_TOUT_SHIFT) +#define UART_UTRSTAT_RX_TOUT_NONE (0x0 << UART_UTRSTAT_RX_TOUT_SHIFT) +#define UART_UTRSTAT_RX_TOUT_TIMEOUT (0x1 << UART_UTRSTAT_RX_TOUT_SHIFT) + +#define UART_UTRSTAT_TX_SHIFT 2 +#define UART_UTRSTAT_TX_MASK (0x1 << UART_UTRSTAT_TX_SHIFT) +#define UART_UTRSTAT_TX_NOT_EMPTY (0x0 << UART_UTRSTAT_TX_SHIFT) +#define UART_UTRSTAT_TX_EMPTY (0x1 << UART_UTRSTAT_TX_SHIFT) + +#define UART_UTRSTAT_TX_BUF_SHIFT 1 +#define UART_UTRSTAT_TX_BUF_MASK (0x1 << UART_UTRSTAT_TX_BUF_SHIFT) +#define UART_UTRSTAT_TX_BUF_NOT_EMPTY (0x0 << UART_UTRSTAT_TX_BUF_SHIFT) +#define UART_UTRSTAT_TX_BUF_EMPTY (0x1 << UART_UTRSTAT_TX_BUF_SHIFT) + +#define UART_UTRSTAT_RX_BUF_SHIFT 0 +#define UART_UTRSTAT_RX_BUF_MASK (0x1 << UART_UTRSTAT_RX_BUF_SHIFT) +#define UART_UTRSTAT_RX_BUF_NOT_EMPTY (0x1 << UART_UTRSTAT_RX_BUF_SHIFT) +#define UART_UTRSTAT_RX_BUF_EMPTY (0x0 << UART_UTRSTAT_RX_BUF_SHIFT) + +/* Rx Error Status register *************************************************/ +#define UART_UERSTAT_BREAK_DETECT 0x8 +#define UART_UERSTAT_FRAME_ERROR 0x4 +#define UART_UERSTAT_PARITY_ERROR 0x2 +#define UART_UERSTAT_OVERRUN_ERROR 0x1 + +/* FIFO status register *****************************************************/ +#define UART_UFSTAT_TX_FIFO_FULL_SHIFT 24 +#define UART_UFSTAT_TX_FIFO_FULL_MASK (0x1 << UART_UFSTAT_TX_FIFO_FULL_SHIFT) +#define UART_UFSTAT_TX_FIFO_FULL (0x1 << UART_UFSTAT_TX_FIFO_FULL_SHIFT) + +#define UART_UFSTAT_TX_FIFO_COUNT_SHIFT 16 +#define UART_UFSTAT_TX_FIFO_COUNT_MASK (0xff << UART_UFSTAT_TX_FIFO_COUNT_SHIFT) + +#define UART_UFSTAT_RX_FIFO_ERROR_SHIFT 9 +#define UART_UFSTAT_RX_FIFO_ERROR_MASK (0x1 << UART_UFSTAT_RX_FIFO_ERROR_SHIFT) +#define UART_UFSTAT_RX_FIFO_ERROR (0x1 << UART_UFSTAT_RX_FIFO_ERROR_SHIFT) + +#define UART_UFSTAT_RX_FIFO_FULL_SHIFT 8 +#define UART_UFSTAT_RX_FIFO_FULL_MASK (0x1 << UART_UFSTAT_RX_FIFO_FULL_SHIFT) +#define UART_UFSTAT_RX_FIFO_FULL (0x1 << UART_UFSTAT_RX_FIFO_FULL_SHIFT) + +#define UART_UFSTAT_RX_FIFO_COUNT_SHIFT 0 +#define UART_UFSTAT_RX_FIFO_COUNT_MASK (0xff << UART_UFSTAT_RX_FIFO_COUNT_SHIFT) + +/* Modem Status register ****************************************************/ +#define UART_UMSTAT_DELTA_CTS_SHIFT 4 +#define UART_UMSTAT_DELTA_CTS_MASK (0x1 << UART_UMSTAT_DELTA_CTS_SHIFT) +#define UART_UMSTAT_DELTA_CTS_NOCHANGE (0x0 << UART_UMSTAT_DELTA_CTS_SHIFT) +#define UART_UMSTAT_DELTA_CTS_CHANGED (0x1 << UART_UMSTAT_DELTA_CTS_SHIFT) + +#define UART_UMSTAT_NCTS_SHIFT 0 +#define UART_UMSTAT_NCTS_MASK (0x1 << UART_UMSTAT_NCTS_SHIFT) +#define UART_UMSTAT_NCTS_HIGH (0x0 << UART_UMSTAT_NCTS_SHIFT) +#define UART_UMSTAT_NCTS_LOW (0x1 << UART_UMSTAT_NCTS_SHIFT) + +/* INterrupt Pending register ***********************************************/ +#define UART_UINTP_MODEM_SHIFT 3 +#define UART_UINTP_MODEM_MASK (0x1 << UART_UINTP_MODEM_SHIFT) +#define UART_UINTP_MODEM (0x1 << UART_UINTP_MODEM_SHIFT) + +#define UART_UINTP_TXD_SHIFT 2 +#define UART_UINTP_TXD_MASK (0x1 << UART_UINTP_TXD_SHIFT) +#define UART_UINTP_TXD (0x1 << UART_UINTP_TXD_SHIFT) + +#define UART_UINTP_ERROR_SHIFT 1 +#define UART_UINTP_ERROR_MASK (0x1 << UART_UINTP_ERROR_SHIFT) +#define UART_UINTP_ERROR (0x1 << UART_UINTP_ERROR_SHIFT) + +#define UART_UINTP_RXD_SHIFT 0 +#define UART_UINTP_RXD_MASK (0x1 << UART_UINTP_RXD_SHIFT) +#define UART_UINTP_RXD (0x1 << UART_UINTP_RXD_SHIFT) + +/* Interrupt Source register ************************************************/ +#define UART_UINTS_MODEM_SHIFT 3 +#define UART_UINTS_MODEM_MASK (0x1 << UART_UINTS_MODEM_SHIFT) +#define UART_UINTS_MODEM (0x1 << UART_UINTS_MODEM_SHIFT) + +#define UART_UINTS_TXD_SHIFT 2 +#define UART_UINTS_TXD_MASK (0x1 << UART_UINTS_TXD_SHIFT) +#define UART_UINTS_TXD (0x1 << UART_UINTS_TXD_SHIFT) + +#define UART_UINTS_ERROR_SHIFT 1 +#define UART_UINTS_ERROR_MASK (0x1 << UART_UINTS_ERROR_SHIFT) +#define UART_UINTS_ERROR (0x1 << UART_UINTS_ERROR_SHIFT) + +#define UART_UINTS_RXD_SHIFT 0 +#define UART_UINTS_RXD_MASK (0x1 << UART_UINTS_RXD_SHIFT) +#define UART_UINTS_RXD (0x1 << UART_UINTS_RXD_SHIFT) + +/* Interrupt Mask register **************************************************/ +#define UART_UINTM_MODEM_SHIFT 3 +#define UART_UINTM_MODEM_MASK (0x1 << UART_UINTM_MODEM_SHIFT) + +#define UART_UINTM_TXD_SHIFT 2 +#define UART_UINTM_TXD_MASK (0x1 << UART_UINTM_TXD_SHIFT) + +#define UART_UINTM_ERROR_SHIFT 1 +#define UART_UINTM_ERROR_MASK (0x1 << UART_UINTM_ERROR_SHIFT) + +#define UART_UINTM_RXD_SHIFT 0 +#define UART_UINTM_RXD_MASK (0x1 << UART_UINTM_RXD_SHIFT) + + +/*----------------------------- S5JS100 ATimer (TIMER) -------------------------------*/ +typedef struct { + __IO uint32_t LOAD_VALUE; /* 0x0 */ + __IO uint32_t CTRL; /* 0x4 */ + __IO uint32_t LOAD_CON_VALUE; /* 0x8 */ + __IO uint32_t INT_STATUS; /* 0xC */ + + __IO uint32_t INT_CLEAR; /* 0x10 */ + __IO uint32_t INT_ENABLE; /* 0x14 */ + __IO uint32_t RSVD3; /* 0x18 */ + __IO uint32_t RSVD4; /* 0x1C */ + + __IO uint32_t RSVD5; /* 0x20 */ + __IO uint32_t RSVD6; /* 0x24 */ + __IO uint32_t RSVD7; /* 0x28 */ + __IO uint32_t RSVD8; /* 0x2C */ + + __IO uint32_t RSVD9; /* 0x30 */ + __IO uint32_t CNT_VALUE; /* 0x34 */ + __IO uint32_t RSVD10; /* 0x38 */ + __IO uint32_t RSVD11; /* 0x3C */ +} S5JS100_TIMER_TypeDef; + +/*----------------------------- S5JS100 USI (UART/SPI/I2C) -------------------------------*/ +typedef struct { + __IO uint32_t CONFIG; // 0x0000 + __IO uint32_t CON; // 0x0004 + __IO uint32_t OPTION; // 0x008~0x014 + __IO uint32_t VERSION; // 0x018 + __IO uint32_t UART_VERSION; // 0x01c + __IO uint32_t SPI_VERSION; // 0x020 + __IO uint32_t I2C_VERSION; // 0x024 + __IO uint32_t FIFO_DEPTH; // 0x028 +} S5JS100_USI_TypeDef; + +#define USI_CONFIG_UART 1 +#define USI_CONFIG_SPI 2 +#define USI_CONFIG_I2C 4 + +#define USI_CON_RST 1 + +#define USI_OPTION_MASTER 1 +#define USI_OPTION_HWACG(x) ((0x3 & (x)) << 1) + +#define USI_VERSION_HW(x) ((x) & 0xFF) +#define USI_VERSION_SW(x) (((x) >> 8) & 0xFF) +#define USI_VERSION_UART(x) (((x) >> 16) & 1) +#define USI_VERSION_SPI(x) (((x) >> 17) & 1) +#define USI_VERSION_USI(x) (((x) >> 24) & 0xFF) + +#define USI_TXFIFO(x) (((x) >> 16) & 0x1FF) +#define USI_RXFIFO(x) ((x) & 0x1FF) + + +/*-------------------- General Purpose Input Output (GPIO) -------------------*/ +/*------------------- Watchdog ----------------------------------------------*/ +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined ( __CC_ARM ) +#pragma pop +#elif defined(__ICCARM__) +/* leave anonymous unions enabled */ +#elif defined(__GNUC__) +/* anonymous unions are enabled by default */ +#elif defined(__TMS470__) +/* anonymous unions are enabled by default */ +#elif defined(__TASKING__) +#pragma warning restore +#else +#warning Not supported compiler type +#endif + + + + +/* ================================================================================ */ +/* ================ Peripheral memory map ================ */ +/* ================================================================================ */ + +/* Peripheral and SRAM base address */ +#define S5JS100_FLASH_BASE 0x00000000 +#define S5JS100_TIMER0_BASE 0x83012000 +#define S5JS100_TIMER1_BASE 0x83012100 +#define S5JS100_USI0_BASE 0x83014000 +#define S5JS100_USI1_BASE 0x83015000 +#define S5JS100_ACPU_SFR_PADDR 0x80000000 +#define S5JS100_MCPU_ROM 0x80140000 +#define S5JS100_MCPU_Debug 0x80150000 +#define S5JS100_MCPU_CTI 0x80158000 +#define S5JS100_PMU_ALIVE 0x81000000 +#define S5JS100_SCMU 0x82000000 +#define S5JS100_EFUSE 0x82010000 +#define S5JS100_PMU_SYS 0x82020000 +#define S5JS100_REG_PAD_CONTROL 0x82021000 +#define S5JS100_ACMU 0x83000000 +#define S5JS100_WDT_BASE 0x83011000 +#define S5JS100_ATIMER 0x83012000 +#define S5JS100_SDIOC 0x83020000 +#define S5JS100_USI0 0x83014000 +#define S5JS100_USI1 0x83015000 +#define S5JS100_SPI 0x83016000 +#define S5JS100_I2C 0x83017000 +#define S5JS100_PWM 0x83018000 +#define S5JS100_SSS_SS 0x83100000 +#define S5JS100_SSS_MB 0x83110000 +#define S5JS100_SSS_KM 0x83120000 +#define S5JS100_PUF 0x83130000 +#define S5JS100_PDMAC 0x83200000 +#define S5JS100_ACPU_BUS_GPV 0x83300000 +#define S5JS100_PPMU_ACPU 0x83400000 +#define S5JS100_MCMU 0x84000000 +#define S5JS100_MWDOG 0x84010000 +#define S5JS100_MTIMER 0x84011000 +#define S5JS100_NBSLEEP 0x84012000 +#define S5JS100_USIM 0x84013000 +#define S5JS100_GIC_DST 0x84100000 +#define S5JS100_GIC_CPU 0x84101000 +#define S5JS100_MDMAC 0x84200000 +#define S5JS100_MCPU_BUS_GPV 0x84300000 +#define S5JS100_MCPU_BUS_CFG 0x84400000 +#define S5JS100_BUS_MONITOR 0x84401000 +#define S5JS100_PPMU_MCPU 0x84410000 +#define S5JS100_MIFCMU 0x85000000 +#define S5JS100_BAAW 0x85010000 +#define S5JS100_QSPI_SFR 0x85020000 +#define S5JS100_GPADCIF0 0x85021000 +#define S5JS100_GPADCIF1 0x85022000 +#define S5JS100_MAILBOX 0x85023000 +#define S5JS100_UART0_BASE 0x85024000 +#define S5JS100_UART1_BASE 0x85025000 +#define S5JS100_GPIO_BASE 0x85026000 +#define S5JS100_PPMU_MCPU2MIF 0x85030000 +#define S5JS100_SYS_CFG 0x85040000 +#define S5JS100_MIF_BUS_GPV 0x85300000 +#define S5JS100_PPMU_ACPU2MIF 0x85400000 +#define S5JS100_RFIP 0x86000000 +#define S5JS100_DCXO_CFG 0x87000000 +#define S5JS100_MCPU2GNSS0 0x88000000 +#define S5JS100_MCPU2GNSS1 0xC0000000 +#define S5JS100_NB_MDM00 0xDC000000 +#define S5JS100_NB_MDM01 0xDC400000 +#define S5JS100_NB_MDM02 0xDC800000 +#define S5JS100_NB_MDM03 0xDCC00000 +#define S5JS100_NB_MDM04 0xDD000000 +#define S5JS100_NB_MDM05 0xDD400000 +#define S5JS100_NB_MDM06 0xDD800000 +#define S5JS100_NB_MDM07 0xDDC00000 +#define S5JS100_NB_MDM08 0xDE000000 +#define S5JS100_NB_MDM09 0xDE400000 +#define S5JS100_NB_MDM10 0xDE800000 +#define S5JS100_NB_MDM11 0xDEC00000 +#define S5JS100_NB_MDM12 0xDF000000 +#define S5JS100_NB_MDM13 0xDF400000 +#define S5JS100_ACPU_CM7_PERI 0xE0000000 +#define S5JS100_BOOTMEM_MIRROR 0xFFFF0000 +/* ================================================================================ */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================ */ + +#define S5JS100_USI0_UART ((S5JS100_USI_UART_TypeDef *) S5JS100_USI0_BASE ) +#define S5JS100_USI1_UART ((S5JS100_USI_UART_TypeDef *) S5JS100_USI1_BASE ) +#define S5JS100_UART0 ((S5JS100_UART_TypeDef *) S5JS100_UART0_BASE ) +#define S5JS100_UART1 ((S5JS100_UART_TypeDef *) S5JS100_UART1_BASE ) +#define S5JS100_TIMER0 ((S5JS100_TIMER_TypeDef *) S5JS100_TIMER0_BASE ) +#define S5JS100_TIMER1 ((S5JS100_TIMER_TypeDef *) S5JS100_TIMER1_BASE ) + +#define S5JS100_USI0_REG ((S5JS100_USI_TypeDef *) (S5JS100_USI0 + 0xC0)) +#define S5JS100_USI1_REG ((S5JS100_USI_TypeDef *) (S5JS100_USI1 + 0xC0)) + +#define S5JS100_SYSCFG_USI0_CONF (*(uint32_t *)(S5JS100_SYS_CFG + 0x1030)) +#define S5JS100_SYSCFG_USI0_IPCLK (*(uint32_t *)(S5JS100_SYS_CFG + 0x1034)) +#define S5JS100_SYSCFG_USI1_CONF (*(uint32_t *)(S5JS100_SYS_CFG + 0x1038)) +#define S5JS100_SYSCFG_USI1_IPCLK (*(uint32_t *)(S5JS100_SYS_CFG + 0x103C)) + + +/********************************************************************* +* GPIO 2 / 3 BIT FEILD POS, OUTPUTS +*************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* S5JS100_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_cmu.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_cmu.h new file mode 100644 index 0000000000..b59cdc402d --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_cmu.h @@ -0,0 +1,378 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __ARCH_ARM_SRC_S5JS100_S5JS100_CMU_H__ +#define __ARCH_ARM_SRC_S5JS100_S5JS100_CMU_H__ + +#define OSCCLK ((unsigned long) 26000000) +#define SLPCLK_CP ((unsigned long) 32000) + +#define S5JS100_SCMU_BASE 0x82000000 +#define S5JS100_ACMU_BASE 0x83000000 +#define S5JS100_MIFCMU_BASE 0x85000000 + +#define ACMU_AP_ACMU_CONTROLLER_OPTION ((S5JS100_ACMU_BASE + 0x800)) +#define ACMU_SPARE0 ((S5JS100_ACMU_BASE + 0x880)) +#define ACMU_VER ((S5JS100_ACMU_BASE + 0x890)) +#define ACMU_ACMU_CONFIG0 ((S5JS100_ACMU_BASE + 0x904)) +#define ACMU_ACMU_CONFIG1 ((S5JS100_ACMU_BASE + 0x908)) +#define ACMU_ACMU_DFSC_CFG0 ((S5JS100_ACMU_BASE + 0x910)) +#define ACMU_ACMU_DFSC_CFG1 ((S5JS100_ACMU_BASE + 0x914)) +#define ACMU_ACMU_DFSC_CTL ((S5JS100_ACMU_BASE + 0x920)) +#define ACMU_ACMU_BUS_ACT_MSK ((S5JS100_ACMU_BASE + 0x950)) +#define ACMU_ACMU_MON_CLK ((S5JS100_ACMU_BASE + 0x9e0)) +#define ACMU_MR_REGISTER_A00 ((S5JS100_ACMU_BASE + 0xa00)) +#define ACMU_MR_REGISTER_A04 ((S5JS100_ACMU_BASE + 0xa04)) +#define ACMU_MR_REGISTER_C00 ((S5JS100_ACMU_BASE + 0xc00)) +#define ACMU_CLK_CON_MUX_CKMUXA_TIMER0_CLK ((S5JS100_ACMU_BASE + 0x1000)) +#define ACMU_CLK_CON_MUX_CKMUXA_TIMER1_CLK ((S5JS100_ACMU_BASE + 0x1004)) +#define ACMU_CLK_CON_MUX_CKMUXA_TIMER2_CLK ((S5JS100_ACMU_BASE + 0x1008)) +#define ACMU_CLK_CON_MUX_CKMUXA_TIMER3_CLK ((S5JS100_ACMU_BASE + 0x100c)) +#define ACMU_CLK_CON_MUX_CKMUXA_TIMER4_CLK ((S5JS100_ACMU_BASE + 0x1010)) +#define ACMU_CLK_CON_MUX_CKMUXA_TIMER5_CLK ((S5JS100_ACMU_BASE + 0x1014)) +#define ACMU_CLK_CON_DIV_CKDIVA_SDIO_CLK ((S5JS100_ACMU_BASE + 0x1804)) +#define ACMU_CLK_CON_DIV_CKDIVA_SPI0_CLK ((S5JS100_ACMU_BASE + 0x1808)) +#define ACMU_CLK_CON_DIV_CKDIVA_USI0_CLK ((S5JS100_ACMU_BASE + 0x1810)) +#define ACMU_CLK_CON_DIV_CKDIVA_USI1_CLK ((S5JS100_ACMU_BASE + 0x1814)) +#define ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK ((S5JS100_ACMU_BASE + 0x1818)) +#define ACMU_CLK_CON_BUF_BUF_AP_SRC_CLK ((S5JS100_ACMU_BASE + 0x2000)) +#define ACMU_CLK_CON_GAT_CKCGA_AP_PERI_CLK ((S5JS100_ACMU_BASE + 0x2004)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_AP_CMU_IPCLKPORT_PCLK ((S5JS100_ACMU_BASE + 0x2008)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_ATIMER0_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x200c)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_ATIMER1_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x2010)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_ATIMER2_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x2014)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_ATIMER3_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x2018)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_ATIMER4_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x201c)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_ATIMER5_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x2020)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_AWDOG_IPCLKPORT_SLPCLK ((S5JS100_ACMU_BASE + 0x2024)) +#define ACMU_CLK_CON_GAT_CLK_AP_UID_PWM_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x2028)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_ACPU2MCPU_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x202c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_ACPU2MIF_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x2030)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2034)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2038)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_PPMU_L2CLK ((S5JS100_ACMU_BASE + 0x203c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_PPMU_L3CLK ((S5JS100_ACMU_BASE + 0x2040)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_APMEM_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2044)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ATIMER0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2048)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ATIMER1_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x204c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ATIMER2_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2050)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ATIMER3_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2054)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ATIMER4_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2058)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_ATIMER5_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x205c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_AWDOG_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2060)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_BS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2064)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_BS_MEM_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2068)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_CM7_IPCLKPORT_L1CLK ((S5JS100_ACMU_BASE + 0x206c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_CM7_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2070)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_CS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2074)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_CS_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2078)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_I2C0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x207c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_PDMA_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2080)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_PUF_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2084)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_PWM_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x2088)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SDIO_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x208c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SDIO_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x2090)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SDIO_IPCLKPORT_SDIO_HCLK ((S5JS100_ACMU_BASE + 0x2094)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SPI0_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x2098)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SPI0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x209c)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SSS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x20a0)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SSS_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x20a4)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_SSS_IPCLKPORT_SLVHCLK ((S5JS100_ACMU_BASE + 0x20a8)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_USI0_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x20ac)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_USI0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x20b0)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_USI1_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x20b4)) +#define ACMU_CLK_CON_GAT_GOUT_AP_UID_USI1_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x20b8)) +#define ACMU_DMYQCH_CON_ABUS_QCH_PPMU_CLK ((S5JS100_ACMU_BASE + 0x3000)) +#define ACMU_DMYQCH_CON_ATIMER0_QCH ((S5JS100_ACMU_BASE + 0x3004)) +#define ACMU_DMYQCH_CON_ATIMER1_QCH ((S5JS100_ACMU_BASE + 0x3008)) +#define ACMU_DMYQCH_CON_ATIMER2_QCH ((S5JS100_ACMU_BASE + 0x300c)) +#define ACMU_DMYQCH_CON_ATIMER3_QCH ((S5JS100_ACMU_BASE + 0x3010)) +#define ACMU_DMYQCH_CON_ATIMER4_QCH ((S5JS100_ACMU_BASE + 0x3014)) +#define ACMU_DMYQCH_CON_ATIMER5_QCH ((S5JS100_ACMU_BASE + 0x3018)) +#define ACMU_DMYQCH_CON_AWDOG_QCH ((S5JS100_ACMU_BASE + 0x301c)) +#define ACMU_DMYQCH_CON_CS_QCH ((S5JS100_ACMU_BASE + 0x3020)) +#define ACMU_DMYQCH_CON_PUF_QCH ((S5JS100_ACMU_BASE + 0x3024)) +#define ACMU_DMYQCH_CON_PWM_QCH_CLK ((S5JS100_ACMU_BASE + 0x3028)) +#define ACMU_DMYQCH_CON_SDIO_QCH_HCLK ((S5JS100_ACMU_BASE + 0x302c)) +#define ACMU_DMYQCH_CON_SPI0_QCH ((S5JS100_ACMU_BASE + 0x3030)) +#define ACMU_DMYQCH_CON_SSS_QCH_DEBUG ((S5JS100_ACMU_BASE + 0x3034)) +#define ACMU_QCH_CON_ABUS_QCH_ACPU2MCPU_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x3038)) +#define ACMU_QCH_CON_ABUS_QCH_ACPU2MIF_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x303c)) +#define ACMU_QCH_CON_ABUS_QCH_L2CLK ((S5JS100_ACMU_BASE + 0x3040)) +#define ACMU_QCH_CON_APMEM_QCH ((S5JS100_ACMU_BASE + 0x3044)) +#define ACMU_QCH_CON_AP_CMU_QCH ((S5JS100_ACMU_BASE + 0x3048)) +#define ACMU_QCH_CON_BS_MEM_QCH ((S5JS100_ACMU_BASE + 0x304c)) +#define ACMU_QCH_CON_BS_QCH ((S5JS100_ACMU_BASE + 0x3050)) +#define ACMU_QCH_CON_CM7_QCH ((S5JS100_ACMU_BASE + 0x3054)) +#define ACMU_QCH_CON_I2C0_QCH ((S5JS100_ACMU_BASE + 0x3058)) +#define ACMU_QCH_CON_PDMA_QCH ((S5JS100_ACMU_BASE + 0x305c)) +#define ACMU_QCH_CON_PWM_QCH_L3CLK ((S5JS100_ACMU_BASE + 0x3060)) +#define ACMU_QCH_CON_SDIO_QCH ((S5JS100_ACMU_BASE + 0x3064)) +#define ACMU_QCH_CON_SSS_QCH ((S5JS100_ACMU_BASE + 0x3068)) +#define ACMU_QCH_CON_USI0_QCH ((S5JS100_ACMU_BASE + 0x306c)) +#define ACMU_QCH_CON_USI1_QCH ((S5JS100_ACMU_BASE + 0x3070)) +#define ACMU_QUEUE_CTRL_REG_AP_CMU ((S5JS100_ACMU_BASE + 0x3c00)) +#define ACMU_DBG_NFO_CKMUXA_TIMER0_CLK ((S5JS100_ACMU_BASE + 0x5000)) +#define ACMU_DBG_NFO_CKMUXA_TIMER1_CLK ((S5JS100_ACMU_BASE + 0x5004)) +#define ACMU_DBG_NFO_CKMUXA_TIMER2_CLK ((S5JS100_ACMU_BASE + 0x5008)) +#define ACMU_DBG_NFO_CKMUXA_TIMER3_CLK ((S5JS100_ACMU_BASE + 0x500c)) +#define ACMU_DBG_NFO_CKMUXA_TIMER4_CLK ((S5JS100_ACMU_BASE + 0x5010)) +#define ACMU_DBG_NFO_CKMUXA_TIMER5_CLK ((S5JS100_ACMU_BASE + 0x5014)) +#define ACMU_DBG_NFO_CKDIVA_ACPU_CLK ((S5JS100_ACMU_BASE + 0x5800)) +#define ACMU_DBG_NFO_CKDIVA_SDIO_CLK ((S5JS100_ACMU_BASE + 0x5808)) +#define ACMU_DBG_NFO_CKDIVA_SPI0_CLK ((S5JS100_ACMU_BASE + 0x580c)) +#define ACMU_DBG_NFO_CKDIVA_USI0_CLK ((S5JS100_ACMU_BASE + 0x5814)) +#define ACMU_DBG_NFO_CKDIVA_USI1_CLK ((S5JS100_ACMU_BASE + 0x5818)) +#define ACMU_DBG_NFO_BUF_AP_SRC_CLK ((S5JS100_ACMU_BASE + 0x6000)) +#define ACMU_DBG_NFO_CKCGA_AP_PERI_CLK ((S5JS100_ACMU_BASE + 0x6004)) +#define ACMU_DBG_NFO_CLK_AP_UID_AP_CMU_IPCLKPORT_PCLK ((S5JS100_ACMU_BASE + 0x6008)) +#define ACMU_DBG_NFO_CLK_AP_UID_ATIMER0_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x600c)) +#define ACMU_DBG_NFO_CLK_AP_UID_ATIMER1_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x6010)) +#define ACMU_DBG_NFO_CLK_AP_UID_ATIMER2_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x6014)) +#define ACMU_DBG_NFO_CLK_AP_UID_ATIMER3_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x6018)) +#define ACMU_DBG_NFO_CLK_AP_UID_ATIMER4_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x601c)) +#define ACMU_DBG_NFO_CLK_AP_UID_ATIMER5_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x6020)) +#define ACMU_DBG_NFO_CLK_AP_UID_AWDOG_IPCLKPORT_SLPCLK ((S5JS100_ACMU_BASE + 0x6024)) +#define ACMU_DBG_NFO_CLK_AP_UID_PWM_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x6028)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ABUS_IPCLKPORT_ACPU2MCPU_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x602c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ABUS_IPCLKPORT_ACPU2MIF_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x6030)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ABUS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6034)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ABUS_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6038)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ABUS_IPCLKPORT_PPMU_L2CLK ((S5JS100_ACMU_BASE + 0x603c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ABUS_IPCLKPORT_PPMU_L3CLK ((S5JS100_ACMU_BASE + 0x6040)) +#define ACMU_DBG_NFO_GOUT_AP_UID_APMEM_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6044)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ATIMER0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6048)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ATIMER1_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x604c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ATIMER2_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6050)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ATIMER3_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6054)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ATIMER4_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6058)) +#define ACMU_DBG_NFO_GOUT_AP_UID_ATIMER5_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x605c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_AWDOG_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6060)) +#define ACMU_DBG_NFO_GOUT_AP_UID_BS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6064)) +#define ACMU_DBG_NFO_GOUT_AP_UID_BS_MEM_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6068)) +#define ACMU_DBG_NFO_GOUT_AP_UID_CM7_IPCLKPORT_L1CLK ((S5JS100_ACMU_BASE + 0x606c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_CM7_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6070)) +#define ACMU_DBG_NFO_GOUT_AP_UID_CS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6074)) +#define ACMU_DBG_NFO_GOUT_AP_UID_CS_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6078)) +#define ACMU_DBG_NFO_GOUT_AP_UID_I2C0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x607c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_PDMA_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6080)) +#define ACMU_DBG_NFO_GOUT_AP_UID_PUF_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6084)) +#define ACMU_DBG_NFO_GOUT_AP_UID_PWM_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x6088)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SDIO_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x608c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SDIO_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x6090)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SDIO_IPCLKPORT_SDIO_HCLK ((S5JS100_ACMU_BASE + 0x6094)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SPI0_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x6098)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SPI0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x609c)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SSS_IPCLKPORT_L2CLK ((S5JS100_ACMU_BASE + 0x60a0)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SSS_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x60a4)) +#define ACMU_DBG_NFO_GOUT_AP_UID_SSS_IPCLKPORT_SLVHCLK ((S5JS100_ACMU_BASE + 0x60a8)) +#define ACMU_DBG_NFO_GOUT_AP_UID_USI0_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x60ac)) +#define ACMU_DBG_NFO_GOUT_AP_UID_USI0_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x60b0)) +#define ACMU_DBG_NFO_GOUT_AP_UID_USI1_IPCLKPORT_CLK ((S5JS100_ACMU_BASE + 0x60b4)) +#define ACMU_DBG_NFO_GOUT_AP_UID_USI1_IPCLKPORT_L3CLK ((S5JS100_ACMU_BASE + 0x60b8)) +#define ACMU_DBG_NFO_DMYQCH_CON_ABUS_QCH_PPMU_CLK ((S5JS100_ACMU_BASE + 0x7000)) +#define ACMU_DBG_NFO_DMYQCH_CON_ATIMER0_QCH ((S5JS100_ACMU_BASE + 0x7004)) +#define ACMU_DBG_NFO_DMYQCH_CON_ATIMER1_QCH ((S5JS100_ACMU_BASE + 0x7008)) +#define ACMU_DBG_NFO_DMYQCH_CON_ATIMER2_QCH ((S5JS100_ACMU_BASE + 0x700c)) +#define ACMU_DBG_NFO_DMYQCH_CON_ATIMER3_QCH ((S5JS100_ACMU_BASE + 0x7010)) +#define ACMU_DBG_NFO_DMYQCH_CON_ATIMER4_QCH ((S5JS100_ACMU_BASE + 0x7014)) +#define ACMU_DBG_NFO_DMYQCH_CON_ATIMER5_QCH ((S5JS100_ACMU_BASE + 0x7018)) +#define ACMU_DBG_NFO_DMYQCH_CON_AWDOG_QCH ((S5JS100_ACMU_BASE + 0x701c)) +#define ACMU_DBG_NFO_DMYQCH_CON_CS_QCH ((S5JS100_ACMU_BASE + 0x7020)) +#define ACMU_DBG_NFO_DMYQCH_CON_PUF_QCH ((S5JS100_ACMU_BASE + 0x7024)) +#define ACMU_DBG_NFO_DMYQCH_CON_PWM_QCH_CLK ((S5JS100_ACMU_BASE + 0x7028)) +#define ACMU_DBG_NFO_DMYQCH_CON_SDIO_QCH_HCLK ((S5JS100_ACMU_BASE + 0x702c)) +#define ACMU_DBG_NFO_DMYQCH_CON_SPI0_QCH ((S5JS100_ACMU_BASE + 0x7030)) +#define ACMU_DBG_NFO_DMYQCH_CON_SSS_QCH_DEBUG ((S5JS100_ACMU_BASE + 0x7034)) +#define ACMU_DBG_NFO_QCH_CON_ABUS_QCH_ACPU2MCPU_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x7038)) +#define ACMU_DBG_NFO_QCH_CON_ABUS_QCH_ACPU2MIF_LH_SI_L2CLK ((S5JS100_ACMU_BASE + 0x703c)) +#define ACMU_DBG_NFO_QCH_CON_ABUS_QCH_L2CLK ((S5JS100_ACMU_BASE + 0x7040)) +#define ACMU_DBG_NFO_QCH_CON_APMEM_QCH ((S5JS100_ACMU_BASE + 0x7044)) +#define ACMU_DBG_NFO_QCH_CON_AP_CMU_QCH ((S5JS100_ACMU_BASE + 0x7048)) +#define ACMU_DBG_NFO_QCH_CON_BS_MEM_QCH ((S5JS100_ACMU_BASE + 0x704c)) +#define ACMU_DBG_NFO_QCH_CON_BS_QCH ((S5JS100_ACMU_BASE + 0x7050)) +#define ACMU_DBG_NFO_QCH_CON_CM7_QCH ((S5JS100_ACMU_BASE + 0x7054)) +#define ACMU_DBG_NFO_QCH_CON_I2C0_QCH ((S5JS100_ACMU_BASE + 0x7058)) +#define ACMU_DBG_NFO_QCH_CON_PDMA_QCH ((S5JS100_ACMU_BASE + 0x705c)) +#define ACMU_DBG_NFO_QCH_CON_PWM_QCH_L3CLK ((S5JS100_ACMU_BASE + 0x7060)) +#define ACMU_DBG_NFO_QCH_CON_SDIO_QCH ((S5JS100_ACMU_BASE + 0x7064)) +#define ACMU_DBG_NFO_QCH_CON_SSS_QCH ((S5JS100_ACMU_BASE + 0x7068)) +#define ACMU_DBG_NFO_QCH_CON_USI0_QCH ((S5JS100_ACMU_BASE + 0x706c)) +#define ACMU_DBG_NFO_QCH_CON_USI1_QCH ((S5JS100_ACMU_BASE + 0x7070)) + +#define SCMU_PLL_LOCKTIME_UPLL ((S5JS100_SCMU_BASE + 0x0)) +#define SCMU_PLL_CON0_UPLL ((S5JS100_SCMU_BASE + 0x100)) +#define SCMU_PLL_CON1_UPLL ((S5JS100_SCMU_BASE + 0x104)) +#define SCMU_PLL_CON2_UPLL ((S5JS100_SCMU_BASE + 0x108)) +#define SCMU_PLL_CON4_UPLL ((S5JS100_SCMU_BASE + 0x110)) +#define SCMU_SYS_SCMU_CONTROLLER_OPTION ((S5JS100_SCMU_BASE + 0x800)) +#define SCMU_SPARE0 ((S5JS100_SCMU_BASE + 0x880)) +#define SCMU_VER ((S5JS100_SCMU_BASE + 0x890)) +#define SCMU_SCMU_MON_CLK ((S5JS100_SCMU_BASE + 0x9e0)) +#define SCMU_MR_REGISTER_A04 ((S5JS100_SCMU_BASE + 0xa04)) +#define SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_AP ((S5JS100_SCMU_BASE + 0x1800)) +#define SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_CP ((S5JS100_SCMU_BASE + 0x1804)) +#define SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_GNSS ((S5JS100_SCMU_BASE + 0x1808)) +#define SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_MIF ((S5JS100_SCMU_BASE + 0x180c)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_EFUSE_IPCLKPORT_CLK ((S5JS100_SCMU_BASE + 0x2000)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_EFUSE_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x2004)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_GNSS_IPCLKPORT_CLK ((S5JS100_SCMU_BASE + 0x2008)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_PADCON_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x200c)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_PMU_SYS_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x2010)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_SYSBUS_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x2014)) +#define SCMU_CLK_CON_GAT_CLK_SYS_UID_SYS_CMU_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x2018)) +#define SCMU_CLK_CON_GAT_CP_SRC_CLK ((S5JS100_SCMU_BASE + 0x201c)) +#define SCMU_CLK_CON_GAT_GNSS_SRC_CLK ((S5JS100_SCMU_BASE + 0x2020)) +#define SCMU_CLK_CON_GAT_MIF_SRC_CLK ((S5JS100_SCMU_BASE + 0x2024)) +#define SCMU_DMYQCH_CON_EFUSE_QCH_CLK ((S5JS100_SCMU_BASE + 0x3000)) +#define SCMU_DMYQCH_CON_GNSS_QCH ((S5JS100_SCMU_BASE + 0x3004)) +#define SCMU_DMYQCH_CON_PADCON_QCH ((S5JS100_SCMU_BASE + 0x3008)) +#define SCMU_DMYQCH_CON_PMU_SYS_QCH ((S5JS100_SCMU_BASE + 0x300c)) +#define SCMU_DMYQCH_CON_SYSBUS_QCH ((S5JS100_SCMU_BASE + 0x3010)) +#define SCMU_QCH_CON_EFUSE_QCH_PCLK ((S5JS100_SCMU_BASE + 0x3014)) +#define SCMU_QCH_CON_SYS_CMU_QCH ((S5JS100_SCMU_BASE + 0x3018)) +#define SCMU_QUEUE_CTRL_REG_SYS_CMU ((S5JS100_SCMU_BASE + 0x3c00)) +#define SCMU_DBG_NFO_UPLL ((S5JS100_SCMU_BASE + 0x4100)) +#define SCMU_DBG_NFO_CKDIVS_UPLL_CLK_AP ((S5JS100_SCMU_BASE + 0x5800)) +#define SCMU_DBG_NFO_CKDIVS_UPLL_CLK_CP ((S5JS100_SCMU_BASE + 0x5804)) +#define SCMU_DBG_NFO_CKDIVS_UPLL_CLK_GNSS ((S5JS100_SCMU_BASE + 0x5808)) +#define SCMU_DBG_NFO_CKDIVS_UPLL_CLK_MIF ((S5JS100_SCMU_BASE + 0x580c)) +#define SCMU_DBG_NFO_CLK_SYS_UID_EFUSE_IPCLKPORT_CLK ((S5JS100_SCMU_BASE + 0x6000)) +#define SCMU_DBG_NFO_CLK_SYS_UID_EFUSE_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x6004)) +#define SCMU_DBG_NFO_CLK_SYS_UID_GNSS_IPCLKPORT_CLK ((S5JS100_SCMU_BASE + 0x6008)) +#define SCMU_DBG_NFO_CLK_SYS_UID_PADCON_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x600c)) +#define SCMU_DBG_NFO_CLK_SYS_UID_PMU_SYS_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x6010)) +#define SCMU_DBG_NFO_CLK_SYS_UID_SYSBUS_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x6014)) +#define SCMU_DBG_NFO_CLK_SYS_UID_SYS_CMU_IPCLKPORT_PCLK ((S5JS100_SCMU_BASE + 0x6018)) +#define SCMU_DBG_NFO_CP_SRC_CLK ((S5JS100_SCMU_BASE + 0x601c)) +#define SCMU_DBG_NFO_GNSS_SRC_CLK ((S5JS100_SCMU_BASE + 0x6020)) +#define SCMU_DBG_NFO_MIF_SRC_CLK ((S5JS100_SCMU_BASE + 0x6024)) +#define SCMU_DBG_NFO_DMYQCH_CON_EFUSE_QCH_CLK ((S5JS100_SCMU_BASE + 0x7000)) +#define SCMU_DBG_NFO_DMYQCH_CON_GNSS_QCH ((S5JS100_SCMU_BASE + 0x7004)) +#define SCMU_DBG_NFO_DMYQCH_CON_PADCON_QCH ((S5JS100_SCMU_BASE + 0x7008)) +#define SCMU_DBG_NFO_DMYQCH_CON_PMU_SYS_QCH ((S5JS100_SCMU_BASE + 0x700c)) +#define SCMU_DBG_NFO_DMYQCH_CON_SYSBUS_QCH ((S5JS100_SCMU_BASE + 0x7010)) +#define SCMU_DBG_NFO_QCH_CON_EFUSE_QCH_PCLK ((S5JS100_SCMU_BASE + 0x7014)) +#define SCMU_DBG_NFO_QCH_CON_SYS_CMU_QCH ((S5JS100_SCMU_BASE + 0x7018)) + +#define MIFCMU_MIF_MIFCMU_CONTROLLER_OPTION ((S5JS100_MIFCMU_BASE + 0x800)) +#define MIFCMU_SPARE0 ((S5JS100_MIFCMU_BASE + 0x880)) +#define MIFCMU_VER ((S5JS100_MIFCMU_BASE + 0x890)) +#define MIFCMU_MIFCMU_MON_CLK ((S5JS100_MIFCMU_BASE + 0x9e0)) +#define MIFCMU_MR_REGISTER_A00 ((S5JS100_MIFCMU_BASE + 0xa00)) +#define MIFCMU_MR_REGISTER_A04 ((S5JS100_MIFCMU_BASE + 0xa04)) +#define MIFCMU_CLK_CON_DIV_CKDIVF_QSPI_CLK ((S5JS100_MIFCMU_BASE + 0x1800)) +#define MIFCMU_CLK_CON_DIV_CKDIVF_SMC_CLK ((S5JS100_MIFCMU_BASE + 0x1804)) +#define MIFCMU_CLK_CON_DIV_CKDIVF_UART0_CLK ((S5JS100_MIFCMU_BASE + 0x1808)) +#define MIFCMU_CLK_CON_DIV_CKDIVF_UART1_CLK ((S5JS100_MIFCMU_BASE + 0x180c)) +#define MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK ((S5JS100_MIFCMU_BASE + 0x1810)) +#define MIFCMU_CLK_CON_BUF_CKBUF_MIF_SRC_CLK ((S5JS100_MIFCMU_BASE + 0x2000)) +#define MIFCMU_CLK_CON_GAT_CLK_MIF_UID_GPADCIF_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x2004)) +#define MIFCMU_CLK_CON_GAT_CLK_MIF_UID_MIF_CMU_IPCLKPORT_PCLK ((S5JS100_MIFCMU_BASE + 0x2008)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_GPADCIF_IPCLKPORT_S0_L3CLK ((S5JS100_MIFCMU_BASE + 0x200c)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_GPADCIF_IPCLKPORT_S1_L3CLK ((S5JS100_MIFCMU_BASE + 0x2010)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_GPIO_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x2014)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_IPCMEM_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x2018)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MBOX_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x201c)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_ACPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x2020)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_BAAW_SFR_L3CLK ((S5JS100_MIFCMU_BASE + 0x2024)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x2028)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_MCPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x202c)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_ACPU2MIF_L2CLK ((S5JS100_MIFCMU_BASE + 0x2030)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_ACPU2MIF_L3CLK ((S5JS100_MIFCMU_BASE + 0x2034)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_MCPU2MIF_L2CLK ((S5JS100_MIFCMU_BASE + 0x2038)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_MCPU2MIF_L3CLK ((S5JS100_MIFCMU_BASE + 0x203c)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_QSPI_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x2040)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_QSPI_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x2044)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SMC_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x2048)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SMC_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x204c)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SYSCFG_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x2050)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_UART0_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x2054)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_UART0_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x2058)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_UART1_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x205c)) +#define MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_UART1_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x2060)) +#define MIFCMU_DMYQCH_CON_GPADCIF_QCH_CLK ((S5JS100_MIFCMU_BASE + 0x3000)) +#define MIFCMU_DMYQCH_CON_GPIO_QCH ((S5JS100_MIFCMU_BASE + 0x3004)) +#define MIFCMU_DMYQCH_CON_MIFBUS_QCH_PPMU_ACPU2MIF_CLK ((S5JS100_MIFCMU_BASE + 0x3008)) +#define MIFCMU_DMYQCH_CON_MIFBUS_QCH_PPMU_MCPU2MIF_CLK ((S5JS100_MIFCMU_BASE + 0x300c)) +#define MIFCMU_DMYQCH_CON_QSPI_QCH ((S5JS100_MIFCMU_BASE + 0x3010)) +#define MIFCMU_DMYQCH_CON_SMC_QCH ((S5JS100_MIFCMU_BASE + 0x3014)) +#define MIFCMU_DMYQCH_CON_SYSCFG_QCH ((S5JS100_MIFCMU_BASE + 0x3018)) +#define MIFCMU_DMYQCH_CON_UART0_QCH ((S5JS100_MIFCMU_BASE + 0x301c)) +#define MIFCMU_DMYQCH_CON_UART1_QCH ((S5JS100_MIFCMU_BASE + 0x3020)) +#define MIFCMU_QCH_CON_GPADCIF_QCH_S0_L3CLK ((S5JS100_MIFCMU_BASE + 0x3024)) +#define MIFCMU_QCH_CON_GPADCIF_QCH_S1_L3CLK ((S5JS100_MIFCMU_BASE + 0x3028)) +#define MIFCMU_QCH_CON_IPCMEM_QCH ((S5JS100_MIFCMU_BASE + 0x302c)) +#define MIFCMU_QCH_CON_MBOX_QCH ((S5JS100_MIFCMU_BASE + 0x3030)) +#define MIFCMU_QCH_CON_MIFBUS_QCH_ACPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x3034)) +#define MIFCMU_QCH_CON_MIFBUS_QCH_BAAW_SFR_L3CLK ((S5JS100_MIFCMU_BASE + 0x3038)) +#define MIFCMU_QCH_CON_MIFBUS_QCH_L2CLK ((S5JS100_MIFCMU_BASE + 0x303c)) +#define MIFCMU_QCH_CON_MIFBUS_QCH_MCPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x3040)) +#define MIFCMU_QCH_CON_MIF_CMU_QCH ((S5JS100_MIFCMU_BASE + 0x3044)) +#define MIFCMU_QUEUE_CTRL_REG_MIF_CMU ((S5JS100_MIFCMU_BASE + 0x3c00)) +#define MIFCMU_DBG_NFO_CKDIVF_MIF_SRC_CLK ((S5JS100_MIFCMU_BASE + 0x5800)) +#define MIFCMU_DBG_NFO_CKDIVF_QSPI_CLK ((S5JS100_MIFCMU_BASE + 0x5804)) +#define MIFCMU_DBG_NFO_CKDIVF_SMC_CLK ((S5JS100_MIFCMU_BASE + 0x5808)) +#define MIFCMU_DBG_NFO_CKDIVF_UART0_CLK ((S5JS100_MIFCMU_BASE + 0x580c)) +#define MIFCMU_DBG_NFO_CKDIVF_UART1_CLK ((S5JS100_MIFCMU_BASE + 0x5810)) +#define MIFCMU_DBG_NFO_CKBUF_MIF_SRC_CLK ((S5JS100_MIFCMU_BASE + 0x6000)) +#define MIFCMU_DBG_NFO_CLK_MIF_UID_GPADCIF_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x6004)) +#define MIFCMU_DBG_NFO_CLK_MIF_UID_MIF_CMU_IPCLKPORT_PCLK ((S5JS100_MIFCMU_BASE + 0x6008)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_GPADCIF_IPCLKPORT_S0_L3CLK ((S5JS100_MIFCMU_BASE + 0x600c)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_GPADCIF_IPCLKPORT_S1_L3CLK ((S5JS100_MIFCMU_BASE + 0x6010)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_GPIO_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x6014)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_IPCMEM_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x6018)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MBOX_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x601c)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_ACPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x6020)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_BAAW_SFR_L3CLK ((S5JS100_MIFCMU_BASE + 0x6024)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x6028)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_MCPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x602c)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_ACPU2MIF_L2CLK ((S5JS100_MIFCMU_BASE + 0x6030)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_ACPU2MIF_L3CLK ((S5JS100_MIFCMU_BASE + 0x6034)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_MCPU2MIF_L2CLK ((S5JS100_MIFCMU_BASE + 0x6038)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_MCPU2MIF_L3CLK ((S5JS100_MIFCMU_BASE + 0x603c)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_QSPI_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x6040)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_QSPI_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x6044)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_SMC_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x6048)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_SMC_IPCLKPORT_L2CLK ((S5JS100_MIFCMU_BASE + 0x604c)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_SYSCFG_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x6050)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_UART0_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x6054)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_UART0_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x6058)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_UART1_IPCLKPORT_CLK ((S5JS100_MIFCMU_BASE + 0x605c)) +#define MIFCMU_DBG_NFO_GOUT_MIF_UID_UART1_IPCLKPORT_L3CLK ((S5JS100_MIFCMU_BASE + 0x6060)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_GPADCIF_QCH_CLK ((S5JS100_MIFCMU_BASE + 0x7000)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_GPIO_QCH ((S5JS100_MIFCMU_BASE + 0x7004)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_MIFBUS_QCH_PPMU_ACPU2MIF_CLK ((S5JS100_MIFCMU_BASE + 0x7008)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_MIFBUS_QCH_PPMU_MCPU2MIF_CLK ((S5JS100_MIFCMU_BASE + 0x700c)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_QSPI_QCH ((S5JS100_MIFCMU_BASE + 0x7010)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_SMC_QCH ((S5JS100_MIFCMU_BASE + 0x7014)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_SYSCFG_QCH ((S5JS100_MIFCMU_BASE + 0x7018)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_UART0_QCH ((S5JS100_MIFCMU_BASE + 0x701c)) +#define MIFCMU_DBG_NFO_DMYQCH_CON_UART1_QCH ((S5JS100_MIFCMU_BASE + 0x7020)) +#define MIFCMU_DBG_NFO_QCH_CON_GPADCIF_QCH_S0_L3CLK ((S5JS100_MIFCMU_BASE + 0x7024)) +#define MIFCMU_DBG_NFO_QCH_CON_GPADCIF_QCH_S1_L3CLK ((S5JS100_MIFCMU_BASE + 0x7028)) +#define MIFCMU_DBG_NFO_QCH_CON_IPCMEM_QCH ((S5JS100_MIFCMU_BASE + 0x702c)) +#define MIFCMU_DBG_NFO_QCH_CON_MBOX_QCH ((S5JS100_MIFCMU_BASE + 0x7030)) +#define MIFCMU_DBG_NFO_QCH_CON_MIFBUS_QCH_ACPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x7034)) +#define MIFCMU_DBG_NFO_QCH_CON_MIFBUS_QCH_BAAW_SFR_L3CLK ((S5JS100_MIFCMU_BASE + 0x7038)) +#define MIFCMU_DBG_NFO_QCH_CON_MIFBUS_QCH_L2CLK ((S5JS100_MIFCMU_BASE + 0x703c)) +#define MIFCMU_DBG_NFO_QCH_CON_MIFBUS_QCH_MCPU2MIF_LH_MI_L2CLK ((S5JS100_MIFCMU_BASE + 0x7040)) +#define MIFCMU_DBG_NFO_QCH_CON_MIF_CMU_QCH ((S5JS100_MIFCMU_BASE + 0x7044)) + +#endif /* __ARCH_ARM_SRC_S5JS100_S5JS100_CMU_H__ */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_hal.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_hal.h new file mode 100644 index 0000000000..3dd4d1e055 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_hal.h @@ -0,0 +1,27 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +typedef enum { + HAL_OK = 0x00, + HAL_ERROR = 0x01, + HAL_BUSY = 0x02, + HAL_TIMEOUT = 0x03 +} HAL_StatusTypeDef; + + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_pwrcal.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_pwrcal.c new file mode 100644 index 0000000000..4fcd68458f --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_pwrcal.c @@ -0,0 +1,479 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "cmsis.h" + +unsigned int cal_clk_is_enabled(unsigned int id) +{ + return 0; +} + +int cal_clk_setrate(unsigned int id, unsigned long rate) +{ + unsigned long parents; + unsigned int div; + unsigned int sel; + + switch (id) { + case p1_upll: + if (rate == 0) { + modifyreg32(SCMU_PLL_CON0_UPLL, (1 << 4), 0 << 4); + modifyreg32(SCMU_PLL_CON0_UPLL, (0x1 << 31), 0); + } else if ((getreg32(SCMU_PLL_CON0_UPLL) & (1 << 31)) == 0) { + modifyreg32(SCMU_PLL_CON0_UPLL, (0x1 << 31), 1); + while (!(getreg32(SCMU_PLL_CON0_UPLL) & (1 << 29))) { + }; + modifyreg32(SCMU_PLL_CON0_UPLL, (1 << 4), 1 << 4); + } + break; + case m1_timer1: + if ((rate >= OSCCLK) || (rate == 0)) { + sel = 0; + } else { + sel = 1; + } + modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER1_CLK, 1, sel); + break; + case m1_timer2: + if ((rate >= OSCCLK) || (rate == 0)) { + sel = 0; + } else { + sel = 1; + } + modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER2_CLK, 1, sel); + break; + case m1_timer3: + if ((rate >= OSCCLK) || (rate == 0)) { + sel = 0; + } else { + sel = 1; + } + modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER3_CLK, 1, sel); + break; + case m1_timer4: + if ((rate >= OSCCLK) || (rate == 0)) { + sel = 0; + } else { + sel = 1; + } + modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER4_CLK, 1, sel); + break; + case m1_timer5: + if ((rate >= OSCCLK) || (rate == 0)) { + sel = 0; + } else { + sel = 1; + } + modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER5_CLK, 1, sel); + break; + case d1_upll_clk_ap: + parents = cal_clk_getrate(p1_upll); + div = (parents + rate - 1) / rate; + if (div > 0xf) { + div = 0xf; + } + modifyreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_AP, 0xF, div - 1); + break; + case d1_upll_clk_cp: + parents = cal_clk_getrate(p1_upll); + div = (parents + rate - 1) / rate; + if (div > 0xf) { + div = 0xf; + } + modifyreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_CP, 0xF, div - 1); + break; + case d1_upll_clk_mif: + parents = cal_clk_getrate(p1_upll); + div = (parents + rate - 1) / rate; + if (div > 0xf) { + div = 0xf; + } + modifyreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_MIF, 0xF, div - 1); + break; + case d1_upll_clk_gnss: + parents = cal_clk_getrate(p1_upll); + div = (parents + rate - 1) / rate; + if (div > 0xf) { + div = 0xf; + } + modifyreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_GNSS, 0xF, div - 1); + break; + case d1_acpu_l1: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x1f) { + div = 0x1f; + } + modifyreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK, 0x1F, div - 1); + break; + case d1_acpu_l2: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x1f) { + div = 0x1f; + } + modifyreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK, 0x1F << 8, (div - 1) << 8); + break; + case d1_acpu_l3: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x1f) { + div = 0x1f; + } + modifyreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK, 0x1F << 16, (div - 1) << 16); + break; + case d1_sdio: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x7f) { + div = 0x7f; + } + modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_SDIO_CLK, 0x7F, div - 1); + break; + case d1_spi0: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + + modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_SPI0_CLK, 0x1F, div - 1); + break; + case d1_usi0: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_USI0_CLK, 0x1F, div - 1); + break; + case d1_usi1: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_USI1_CLK, 0x1F, div - 1); + break; + case d1_mif_l2: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (parents + rate - 1) / rate; + if (div > 0x1f) { + div = 0x1f; + } + modifyreg32(MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK, 0x1F << 0, (div - 1) << 0); + break; + case d1_mif_l3: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (parents + rate - 1) / rate; + if (div > 0x1f) { + div = 0x1f; + } + modifyreg32(MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK, 0x1F << 8, (div - 1) << 8); + break; + case d1_qspi: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_QSPI_CLK, 0x1F, div - 1); + break; + case d1_smc: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_SMC_CLK, 0x1F, div - 1); + break; + case d1_uart0: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_UART0_CLK, 0x1F, div - 1); + break; + case d1_uart1: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (parents + rate - 1) / rate; + if (div > 0x1F) { + div = 0x1F; + } + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_UART1_CLK, 0x1F, div - 1); + break; + default: + break; + } + + return 0; +} + +unsigned long cal_clk_getrate(unsigned int id) +{ + unsigned long parents; + unsigned long rate = 0; + unsigned long div; + + switch (id) { + case p1_upll: + if (((getreg32(SCMU_PLL_CON0_UPLL) >> 4) & 1) == 0) { + rate = OSCCLK; + } else { + unsigned long p, m, s; + p = (getreg32(SCMU_PLL_CON0_UPLL) >> 8) & 0x3f; + m = (getreg32(SCMU_PLL_CON0_UPLL) >> 16) & 0x3ff; + s = (getreg32(SCMU_PLL_CON0_UPLL) >> 0) & 0x7; + rate = (OSCCLK / p * m) >> s; + } + break; + case m1_timer0: + if ((getreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER0_CLK) & 1) == 0) { + rate = OSCCLK; + } else { + rate = SLPCLK_CP; + } + break; + case m1_timer1: + if ((getreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER1_CLK) & 1) == 0) { + rate = OSCCLK; + } else { + rate = SLPCLK_CP; + } + break; + case m1_timer2: + if ((getreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER2_CLK) & 1) == 0) { + rate = OSCCLK; + } else { + rate = SLPCLK_CP; + } + break; + case m1_timer3: + if ((getreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER3_CLK) & 1) == 0) { + rate = OSCCLK; + } else { + rate = SLPCLK_CP; + } + break; + case m1_timer4: + if ((getreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER4_CLK) & 1) == 0) { + rate = OSCCLK; + } else { + rate = SLPCLK_CP; + } + break; + case m1_timer5: + if ((getreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER5_CLK) & 1) == 0) { + rate = OSCCLK; + } else { + rate = SLPCLK_CP; + } + break; + case d1_upll_clk_ap: + parents = cal_clk_getrate(p1_upll); + div = (getreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_AP) & 0xF) + 1; + rate = parents / div; + break; + case d1_upll_clk_cp: + parents = cal_clk_getrate(p1_upll); + div = (getreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_CP) & 0xF) + 1; + rate = parents / div; + break; + case d1_upll_clk_mif: + parents = cal_clk_getrate(p1_upll); + div = (getreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_MIF) & 0xF) + 1; + rate = parents / div; + break; + case d1_upll_clk_gnss: + parents = cal_clk_getrate(p1_upll); + div = (getreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_GNSS) & 0xF) + 1; + rate = parents / div; + break; + case d1_acpu_l1: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (getreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_acpu_l2: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = ((getreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK) >> 8) & 0x1F) + 1; + rate = parents / div; + break; + case d1_acpu_l3: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = ((getreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK) >> 16) & 0x1F) + 1; + rate = parents / div; + break; + case d1_sdio: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (getreg32(ACMU_CLK_CON_DIV_CKDIVA_SDIO_CLK) & 0x7F) + 1; + rate = parents / div; + break; + case d1_spi0: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (getreg32(ACMU_CLK_CON_DIV_CKDIVA_SPI0_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_usi0: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (getreg32(ACMU_CLK_CON_DIV_CKDIVA_USI0_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_usi1: + parents = cal_clk_getrate(d1_upll_clk_ap); + div = (getreg32(ACMU_CLK_CON_DIV_CKDIVA_USI1_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_mif_l2: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = ((getreg32(MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK) >> 0) & 0x1F) + 1; + rate = parents / div; + break; + case d1_mif_l3: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = ((getreg32(MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK) >> 8) & 0x1F) + 1; + rate = parents / div; + break; + case d1_qspi: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (getreg32(MIFCMU_CLK_CON_DIV_CKDIVF_QSPI_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_smc: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (getreg32(MIFCMU_CLK_CON_DIV_CKDIVF_SMC_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_uart0: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (getreg32(MIFCMU_CLK_CON_DIV_CKDIVF_UART0_CLK) & 0x1F) + 1; + rate = parents / div; + break; + case d1_uart1: + parents = cal_clk_getrate(d1_upll_clk_mif); + div = (getreg32(MIFCMU_CLK_CON_DIV_CKDIVF_UART1_CLK) & 0x1F) + 1; + rate = parents / div; + break; + default: + break; + } + + return rate; +} + +int cal_clk_enable(unsigned int id) +{ + switch (id) { + case p1_upll: + modifyreg32(SCMU_PLL_CON0_UPLL, (0x1 << 31), 1); + while (!(getreg32(SCMU_PLL_CON0_UPLL) & (1 << 29))) { + }; + modifyreg32(SCMU_PLL_CON0_UPLL, (1 << 4), 1 << 4); + break; + default: + break; + } + return 0; +} + +int cal_clk_disable(unsigned int id) +{ + switch (id) { + case p1_upll: + modifyreg32(SCMU_PLL_CON0_UPLL, (1 << 4), 0 << 4); + modifyreg32(SCMU_PLL_CON0_UPLL, (0x1 << 31), 0); + break; + default: + break; + } + return 0; +} + +int cal_init(void) +{ + /* disable 0 value setting to reduce binary size */ + + /* enable UPLL */ + modifyreg32(SCMU_PLL_CON0_UPLL, (0x3ff << 16), (0x18c << 16)); + modifyreg32(SCMU_PLL_CON0_UPLL, (0x1 << 31), (1 << 31)); + + modifyreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_AP, 0xf, 1); + /* need to fix to 0x1 */ + modifyreg32(SCMU_CLK_CON_DIV_CKDIVS_UPLL_CLK_MIF, 0xf, 0x1); + + // modifyreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK, (0x1f << 0), 0); /* L1 CLK */ + // modifyreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK, (0x1f << 8), 0); /* L2 CLK */ + modifyreg32(ACMU_CLK_CON_DIV_MULTI3_CKDIVA_ACPU_CLK, (0x1f << 16), 1 << 16); /* L3 CLK */ + + // modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_SDIO_CLK, 0x7f, 0); + modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_SPI0_CLK, 0x1f, 1); + // modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_USI0_CLK, 0x1f, 0); + // modifyreg32(ACMU_CLK_CON_DIV_CKDIVA_USI1_CLK, 0x1f, 0); + + // modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER0_CLK, 0x1, 0); + // modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER1_CLK, 0x1, 0); + // modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER2_CLK, 0x1, 0); + // modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER3_CLK, 0x1, 0); + // modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER4_CLK, 0x1, 0); + // modifyreg32(ACMU_CLK_CON_MUX_CKMUXA_TIMER5_CLK, 0x1, 0); + + // modifyreg32(MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK, (0x1f << 0), 0); /* L2 CLK */ + modifyreg32(MIFCMU_CLK_CON_DIV_MULTI2_CKDIVF_MIF_SRC_CLK, (0x1f << 8), 1 << 8); /* L3 CLK */ + + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_QSPI_CLK, 0x1f, 4); //QSPI_CLK to be 40Mhz as first + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_SMC_CLK, 0x1f, 1); + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_UART0_CLK, 0x1f, 1); + modifyreg32(MIFCMU_CLK_CON_DIV_CKDIVF_UART1_CLK, 0x1f, 1); + + /* wait for UPLL lock */ + while (!(getreg32(SCMU_PLL_CON0_UPLL) & (1 << 29))) { + }; + modifyreg32(SCMU_PLL_CON0_UPLL, (0x1 << 4), (1 << 4)); +#if 0 + /* Q-CHANNEL enable */ + //modifyreg32(ACMU_AP_ACMU_CONTROLLER_OPTION, (0x3 << 28), (0x3 << 28)); + modifyreg32(SCMU_SYS_SCMU_CONTROLLER_OPTION, (0x3 << 28), (0x3 << 28)); + modifyreg32(MIFCMU_MIF_MIFCMU_CONTROLLER_OPTION, (0x3 << 28), (0x3 << 28)); + /* BUS_FREQ_EN, MIN_FREQ_EN enable */ + modifyreg32(ACMU_ACMU_DFSC_CTL, (0x3 << 1), (0x3 << 1)); +#endif + + /* PDMAC Q-CH workaround */ + putreg32(0x4046, ACMU_ACMU_BUS_ACT_MSK); + + /* Gate clocks of unused peripherals */ + // SDIO HOST + putreg32(0x100000, ACMU_CLK_CON_GAT_GOUT_AP_UID_SDIO_IPCLKPORT_CLK); + putreg32(0x100000, ACMU_CLK_CON_GAT_GOUT_AP_UID_SDIO_IPCLKPORT_L2CLK); + putreg32(0x100000, ACMU_CLK_CON_GAT_GOUT_AP_UID_SDIO_IPCLKPORT_SDIO_HCLK); + + // PPMUs + putreg32(0x100000, ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_PPMU_L2CLK); + putreg32(0x100000, ACMU_CLK_CON_GAT_GOUT_AP_UID_ABUS_IPCLKPORT_PPMU_L3CLK); + putreg32(0x100000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_ACPU2MIF_L2CLK); + putreg32(0x100000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_ACPU2MIF_L3CLK); + putreg32(0x100000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_MCPU2MIF_L2CLK); + putreg32(0x100000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_MIFBUS_IPCLKPORT_PPMU_MCPU2MIF_L3CLK); + + // SMC + putreg32(0x100000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SMC_IPCLKPORT_CLK); + putreg32(0x100000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SMC_IPCLKPORT_L2CLK); + return 0; +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_systemreset.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_systemreset.c new file mode 100644 index 0000000000..aebd097bc5 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_systemreset.c @@ -0,0 +1,332 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 : s5js100_systemreset.c + * @brief : board reset source file + * @date : June 2019 + * + * @note : Add chip dependent feature and more detail error status + * + */ + + +/**************************************************************************** + Included Files + ****************************************************************************/ +#include "cmsis.h" +#include "mbed_crash_data_offsets.h" +#include "mbed_retarget.h" +#include "mbed_critical.h" +#include "mbed_error.h" +#include "mbed_error_hist.h" +#include "mbed_interface.h" +#include "mbed_power_mgmt.h" +#include "mbed_stats.h" +#include "mbed_atomic.h" +#include "mbed_fault_handler.h" + +#include "rtx_os.h" +#include +#include +#ifndef NDEBUG +#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) print_error_report(ctx, error_msg, error_filename, error_line) +static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line); +#else +#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0) +#endif +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED +//Global for populating the context in exception handler +//mbed_fault_context_t *const mbed_fault_context = (mbed_fault_context_t *)(FAULT_CONTEXT_LOCATION); +#else +//mbed_fault_context_t fault_context; +//mbed_fault_context_t *const mbed_fault_context = (mbed_fault_context_t *) &fault_context; +#endif + +extern mbed_fault_context_t *mbed_fault_context; +static int error_count = 0; +static mbed_error_ctx first_error_ctx = {0}; +static mbed_error_ctx last_error_ctx = {0}; +static mbed_error_hook_t error_hook = NULL; +static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller); + +static inline const char *name_or_unnamed(const char *name) +{ + return name ? name : ""; +} + + +#ifndef NDEBUG +#define GET_TARGET_NAME_STR(tgt_name) #tgt_name +#define GET_TARGET_NAME(tgt_name) GET_TARGET_NAME_STR(tgt_name) +static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, const char *error_filename, int error_line) +{ + int error_code = MBED_GET_ERROR_CODE(ctx->error_status); + int error_module = MBED_GET_ERROR_MODULE(ctx->error_status); + + mbed_error_printf("\n\n++ MbedOS Error Info ++\nError Status: 0x%X Code: %d Module: %d\nError Message: ", ctx->error_status, error_code, error_module); + + switch (error_code) { + //These are errors reported by kernel handled from mbed_rtx_handlers + case MBED_ERROR_CODE_RTOS_EVENT: + mbed_error_printf("Kernel Error: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_THREAD_EVENT: + mbed_error_printf("Thread: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_MUTEX_EVENT: + mbed_error_printf("Mutex: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_SEMAPHORE_EVENT: + mbed_error_printf("Semaphore: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_MEMORY_POOL_EVENT: + mbed_error_printf("MemoryPool: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_EVENT_FLAGS_EVENT: + mbed_error_printf("EventFlags: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_TIMER_EVENT: + mbed_error_printf("Timer: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT: + mbed_error_printf("MessageQueue: 0x%" PRIX32 ", ", ctx->error_value); + break; + + case MBED_ERROR_CODE_ASSERTION_FAILED: + mbed_error_printf("Assertion failed: "); + break; + + default: + //Nothing to do here, just print the error info down + break; + } + mbed_error_puts(error_msg); + mbed_error_printf("\nLocation: 0x%" PRIX32, ctx->error_address); + + /* We print the filename passed in, not any filename in the context. This + * avoids the console print for mbed_error being limited to the presence + * and length of the filename storage. Note that although the MBED_ERROR + * macro compiles out filenames unless platform.error-filename-capture-enabled + * is turned on, MBED_ASSERT always passes filenames, and other direct + * users of mbed_error() may also choose to. + */ + if (error_filename) { + mbed_error_puts("\nFile: "); + mbed_error_puts(error_filename); + mbed_error_printf("+%d", error_line); + } + + mbed_error_printf("\nError Value: 0x%" PRIX32, ctx->error_value); +#ifdef MBED_CONF_RTOS_PRESENT + mbed_error_printf("\nCurrent Thread: %s Id: 0x%" PRIX32 " Entry: 0x%" PRIX32 " StackSize: 0x%" PRIX32 " StackMem: 0x%" PRIX32 " SP: 0x%" PRIX32 " ", + name_or_unnamed(((osRtxThread_t *)ctx->thread_id)->name), + ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem, ctx->thread_current_sp); +#endif + +#if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT) + mbed_error_printf("\nNext:"); + print_thread(osRtxInfo.thread.run.next); + + mbed_error_printf("\nReady:"); + print_threads_info(osRtxInfo.thread.ready.thread_list); + + mbed_error_printf("\nWait:"); + print_threads_info(osRtxInfo.thread.wait_list); + + mbed_error_printf("\nDelay:"); + print_threads_info(osRtxInfo.thread.delay_list); +#endif +#if !defined(MBED_SYS_STATS_ENABLED) + mbed_error_printf("\nFor more info, visit: https://mbed.com/s/error?error=0x%08X&tgt=" GET_TARGET_NAME(TARGET_NAME), ctx->error_status); +#else + mbed_stats_sys_t sys_stats; + mbed_stats_sys_get(&sys_stats); + mbed_error_printf("\nFor more info, visit: https://mbed.com/s/error?error=0x%08X&osver=%" PRId32 "&core=0x%08" PRIX32 "&comp=%d&ver=%" PRIu32 "&tgt=" GET_TARGET_NAME(TARGET_NAME), ctx->error_status, sys_stats.os_version, sys_stats.cpu_id, sys_stats.compiler_id, sys_stats.compiler_version); +#endif + mbed_error_printf("\n-- MbedOS Error Info --\n"); +} +#endif //ifndef NDEBUG + + + + +/**************************************************************************** + * Name: up_systemreset + * + * Description: + * Internal, reset logic. + * + ****************************************************************************/ +static void up_systemreset(void) +{ + putreg32(0x1, 0x8301100C); + putreg32(0x1 << 1, 0x82020018); + + putreg32(0x4, 0x83011000); // enable watchdog + putreg32(0x1, 0x83011010); + putreg32(0x1, 0x83011020); + putreg32(327, 0x83011004); //set 10ms to be reset , 1 sec=32768 + putreg32(0xFF, 0x83011008); // force to load value to be reset + + /* Wait for the reset */ + for (; ;) { + } +} + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. This function may or may not be supported by a + * particular board architecture. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not used by + * a board, the value zero may be provided in calls to board_reset. + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ +int board_reset(void) +{ + up_systemreset(); + return 0; +} +//Set an error status with the error handling system +static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller) +{ + mbed_error_ctx current_error_ctx; + + //Error status should always be < 0 + if (error_status >= 0) { + //This is a weird situation, someone called mbed_error with invalid error code. + //We will still handle the situation but change the error code to ERROR_INVALID_ARGUMENT, atleast the context will have info on who called it + error_status = MBED_ERROR_INVALID_ARGUMENT; + } + + //Clear the context capturing buffer + memset(¤t_error_ctx, 0, sizeof(mbed_error_ctx)); + //Capture error information + current_error_ctx.error_status = error_status; + current_error_ctx.error_address = (uint32_t)caller; + current_error_ctx.error_value = error_value; +#ifdef MBED_CONF_RTOS_PRESENT + //Capture thread info + osRtxThread_t *current_thread = osRtxInfo.thread.run.curr; + current_error_ctx.thread_id = (uint32_t)current_thread; + current_error_ctx.thread_entry_address = (uint32_t)current_thread->thread_addr; + current_error_ctx.thread_stack_size = current_thread->stack_size; + current_error_ctx.thread_stack_mem = (uint32_t)current_thread->stack_mem; + current_error_ctx.thread_current_sp = (uint32_t)¤t_error_ctx; // Address local variable to get a stack pointer +#endif //MBED_CONF_RTOS_PRESENT + +#if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED + //Capture filename/linenumber if provided + //Index for tracking error_filename + strncpy(current_error_ctx.error_filename, filename, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN); + current_error_ctx.error_line_number = line_number; +#endif + + //Prevent corruption by holding out other callers + core_util_critical_section_enter(); + + //Increment error count + error_count++; + + //Capture the first system error and store it + if (error_count == 1) { //first error + memcpy(&first_error_ctx, ¤t_error_ctx, sizeof(mbed_error_ctx)); + } + + //copy this error to last error + memcpy(&last_error_ctx, ¤t_error_ctx, sizeof(mbed_error_ctx)); + +#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED + //Log the error with error log + mbed_error_hist_put(¤t_error_ctx); +#endif + + //Call the error hook if available + if (error_hook != NULL) { + error_hook(&last_error_ctx); + } + + core_util_critical_section_exit(); + + return MBED_SUCCESS; +} + +#define CONTAINER_OF(ptr, type, field) \ + ((type *)(((char *)(ptr)) - offsetof(type, field))) + +mbed_error_status_t mbed_error(int error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) +{ + int i; + uint32_t current_psp; + //set the error reported + (void) handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR()); + + //On fatal errors print the error context/report + ERROR_REPORT(&last_error_ctx, error_msg, filename, line_number); + //mbed_error_printf("\nPSP 0x%x\n", mbed_fault_context->PSP); + current_psp = mbed_fault_context->PSP; + mbed_error_printf("dump PSP[0x%x] \n", (unsigned int)current_psp); + mbed_error_printf("====================== CUT ========================= \n"); + + if (current_psp != 0x0) { + //dump stack contents + for (i = 0; getreg32(current_psp) != 0xDEADBEEF; i++) { + if (i % 0x8 == 0) { + mbed_error_printf("\n"); + mbed_error_printf("0x%.8x:", (unsigned int)current_psp); + } + mbed_error_printf("0x%.8x ", getreg32(current_psp)); + current_psp += 4; + } + // last STACK Pointer + mbed_error_printf("0x%.8x ", getreg32(current_psp)); + } + mbed_error_printf("\n======================FOR ERROR DUMP ========================= \n"); + while (1); +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_type.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_type.h new file mode 100644 index 0000000000..fe355d6742 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_type.h @@ -0,0 +1,31 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 S5JS100_TYPE_H +#define S5JS100_TYPE_H + +#define getreg8(a) (*(volatile unsigned char *)(a)) +#define putreg8(v, a) (*(volatile unsigned char *)(a) = (v)) +#define getreg32(a) (*(volatile unsigned int *)(a)) +#define putreg32(v, a) (*(volatile unsigned int *)(a) = (v)) +#define modifyreg32(a, m, v) putreg32((((getreg32(a)) & ~(m)) | ((v) & (m))), (a)) + +#define is_evt0() (((getreg32(0x82010000)) & 0xF0) == 0) + +#endif /* S5JS100_TYPE_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_vclk.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_vclk.h new file mode 100644 index 0000000000..1f717dc2b7 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/s5js100_vclk.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_VCLK_H__ +#define __S5JS100_VCLK_H__ +#ifdef __cplusplus +extern "C" { +#endif +enum { + gate_dummy = 0x0A000000, + vclk_group_grpgate_end, + num_of_grpgate = vclk_group_grpgate_end - 0x0A000000, + + sclk_dummy = 0x0A010000, + vclk_group_m1d1g1_end, + num_of_m1d1g1 = vclk_group_m1d1g1_end - 0x0A010000, + + p1_upll = 0x0A020000, + vclk_group_p1_end, + num_of_p1 = vclk_group_p1_end - 0x0A020000, + + m1_timer0 = 0x0A030000, + m1_timer1, + m1_timer2, + m1_timer3, + m1_timer4, + m1_timer5, + vclk_group_m1_end, + num_of_m1 = vclk_group_m1_end - 0x0A030000, + + d1_upll_clk_ap = 0x0A040000, + d1_upll_clk_cp, + d1_upll_clk_mif, + d1_upll_clk_gnss, + d1_acpu_l1, + d1_acpu_l2, + d1_acpu_l3, + d1_sdio, + d1_spi0, + d1_usi0, + d1_usi1, + d1_mif_l2, + d1_mif_l3, + d1_qspi, + d1_smc, + d1_uart0, + d1_uart1, + vclk_group_d1_end, + num_of_d1 = vclk_group_d1_end - 0x0A040000, + + pxmxdx_top = 0x0A050000, + vclk_group_pxmxdx_end, + num_of_pxmxdx = vclk_group_pxmxdx_end - 0x0A050000, + + umux_dummy = 0x0A060000, + vclk_group_umux_end, + num_of_umux = vclk_group_umux_end - 0x0A060000, + + dvfs_dummy = 0x0A070000, + vclk_group_dfs_end, + num_of_dfs = vclk_group_dfs_end - 0x0A070000, +}; + +extern int cal_clk_setrate(unsigned int id, unsigned long rate); +extern unsigned long cal_clk_getrate(unsigned int id); + +extern int cal_clk_enable(unsigned int id); +extern int cal_clk_disable(unsigned int id); +#ifdef __cplusplus +} +#endif +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.cpp new file mode 100755 index 0000000000..b621fe698a --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.cpp @@ -0,0 +1,490 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +#include +#include "mbed.h" +#include "stdlib.h" +#include "cmsis.h" +#include "mbed_wait_api.h" +#include "flash_api.h" + + +/**************************************************************************** + * Private Data + ****************************************************************************/ +int flash_no_erase; +int flash_idx = 0; +#define S5JS100_FLASH_DELAYTIME 1 +#define S5JS100_FLASH_WRITEUNIT 32 +#define CACHE_LINE_MASK 0xffffffe0 +#define CACHE_LINE_SIZE 32 +Semaphore *g_sem = new Semaphore(1); +//int sflash_init=0; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static void hw_delay_us(unsigned int Value) +{ + volatile unsigned i, j; + + for (i = 0; i < (Value * 2); i++) + for (j = 0; j < 100; j++); +} + +unsigned int up_progmem_blocksize(void) +{ + return S5JS100_FLASH_BLOCK_SIZE; +} +/* +static void sflash_set_page_size(eQSPI_PAGE_SIZE size) +{ + //Bytes per Page + modifyreg32(S5JS100_SFLASH_SFCON, 0xF << 8, size << 8); +} +*/ +static unsigned int up_progmem_npages(void) +{ + return S5JS100_FLASH_SIZE / S5JS100_FLASH_PAGE_SIZE; +} + +static int up_progmem_getaddress(int page) +{ + return S5JS100_FLASH_PADDR + S5JS100_FLASH_PAGE_SIZE * page; +} + +int up_progmem_getpage(int addr) +{ + return (addr - S5JS100_FLASH_PADDR) / S5JS100_FLASH_PAGE_SIZE; +} + + +static void s5js100_sflash_disable_wp(void) +{ + /* someone has been disabled wp, we should wait until it's released */ + while (getreg32(S5JS100_SFLASH_SFCON) & SFLASH_SFCON_WP_DISABLE) ; + modifyreg32(S5JS100_SFLASH_SFCON, SFLASH_SFCON_WP_MASK, SFLASH_SFCON_WP_DISABLE); +} + +static void s5js100_sflash_enable_wp(void) +{ + modifyreg32(S5JS100_SFLASH_SFCON, SFLASH_SFCON_WP_MASK, SFLASH_SFCON_WP_ENABLE); +} + +static uint8_t s5js100_sflash_read_status(void) +{ + return getreg8(S5JS100_SFLASH_RDSR); +} + +/* return FLASH capacity in BYTE */ +uint32_t s5js100_sflash_read_capacity(void) +{ + uint32_t capacity_type; + capacity_type = (getreg32(S5JS100_SFLASH_RDID) & (0xFF << 16)) >> 16; + capacity_type = (0x1 << ((capacity_type & 0xF) - 1)) * 1024 * 1024; + return capacity_type / 8; +} + +int s5js100_sflash_write_protect(eQSPI_PROTECTION_AREA area) +{ + int status_register; + + s5js100_sflash_disable_wp(); + + status_register = getreg8(S5JS100_SFLASH_RDSR); + //lldbg("status_register : 0x%x, area : 0x%x\n", status_register, area); + + /* send Write Enable */ + putreg8(1, S5JS100_SFLASH_WREN); + while (!(getreg8(S5JS100_SFLASH_RDSR) & 0x2)); + + /* write status register */ + status_register = (status_register & 0x83) | (area << 2); + //lldbg("status_register write : 0x%x ==> ", status_register); + putreg32(status_register | 0x0200, S5JS100_SFLASH_WRSR); + while (getreg8(S5JS100_SFLASH_RDSR) & 0x1); + + status_register = getreg8(S5JS100_SFLASH_RDSR); + //lldbg("0x%x\n", status_register); + + /* send Write Disable */ + putreg8(1, S5JS100_SFLASH_WRDI); + while (getreg8(S5JS100_SFLASH_RDSR) & 0x2); + + s5js100_sflash_enable_wp(); + + return 0; +} + + + +/* SFlash_DriverInitialize: SFlash Driver Initialize function */ +void SFlash_DriverInitialize() +{ + putreg32(0x8660060A, S5JS100_SFLASH_SFCON); /*disable write protect for FLASH stage changing*/ + modifyreg32(0x85020074, 0x1, 1); /*Set FAST READ */ + + /* Enable Quad Read */ + putreg32(0x4, S5JS100_SFLASH_IO_MODE); + putreg32(0x8, S5JS100_SFLASH_PERF_MODE); + + // command 3. RDSR2 read winbond Status Register 2 + modifyreg32(0x85020024, 0xFF, 0x35); //Set QE to Status2 + + while (!(getreg8(S5JS100_SFLASH_BASE + 0xDC) & (0x1 << 1))) { + }; /* Check FLASH has Quad Enabled */ + + cal_clk_setrate(d1_qspi, 100000000); + putreg32(0x0660061A, S5JS100_SFLASH_SFCON); //enable write protect + winbond + byte program + + /* change drive strength */ + modifyreg32(0x82021070, 0x3 << 8, 0x0 << 8); //Drive strength CS to (0x0)2mA + modifyreg32(0x82021074, 0x3 << 8, 0x0 << 8); //Drive strength SCK to (x0)2mA + modifyreg32(0x82021078, 0x3 << 8, 0x0 << 8); //Drive strength SI to (0x0)2mA + modifyreg32(0x8202107C, 0x3 << 8, 0x0 << 8); //Drive strength SO to (0x0)2mA + modifyreg32(0x82021080, 0x3 << 8, 0x0 << 8); //Drive strength WP to (0x0)2mA + modifyreg32(0x82021084, 0x3 << 8, 0x0 << 8); //Drive strength HLD to (0x0)2mA + + s5js100_sflash_write_protect(SFLASH_PROTECTION_NONE); +} + +extern "C" { + void s5js100_sflash_reinit(void) + { + cal_clk_setrate(d1_qspi, 100000000); + } +} + +static void local_memcpy(void *dst, void *src, size_t n) +{ + unsigned char *pout = (unsigned char *)dst; + unsigned char *pin = (unsigned char *)src; + while (n-- > 0) { + *pout++ = *pin++; + //hw_delay_us(100 * S5JS100_FLASH_DELAYTIME); + //printf("."); + } +} + +static int up_progmem_write_disabledcache(unsigned int addr, const void *buf, int count) +{ + int remain = count; + char *pos = (char *)buf; + + g_sem->try_acquire(); + while (remain) { + int tmp = remain; + + if (tmp > S5JS100_FLASH_WRITEUNIT) { + tmp = S5JS100_FLASH_WRITEUNIT; + } + + s5js100_sflash_disable_wp(); + + /* Temporary code for testing */ + //memcpy((void *)(addr + S5JS100_SFLASH_WOFFSET), (void *)(pos), tmp); + local_memcpy((void *)(addr + S5JS100_SFLASH_WOFFSET), (void *)(pos), tmp); + + /* Flash Mirror Address is device attribute, need to POC with Flash Read Address */ + /* invalidate cache for read address, not read and write in POC state */ + /* CM7 cache line 32bytes, align 32bytes */ + invalidate_dcache_by_addr((uint32_t *)(addr & CACHE_LINE_MASK), tmp + CACHE_LINE_SIZE); + + s5js100_sflash_enable_wp(); + + pos += tmp; + addr += tmp; + remain -= tmp; + + hw_delay_us(1000 * S5JS100_FLASH_DELAYTIME); + } + g_sem->release(); + + return count; +} + + +int sflash_write(unsigned int addr, unsigned char *buf, int count) +{ + unsigned int uf_start = (unsigned int)S5JS100_FLASH_FS_PADDR; + unsigned int uf_end = S5JS100_FLASH_PADDR + S5JS100_FLASH_SIZE; + /* + * Check the request address is in a specific userflash area + * We assumed that the userflash area's address is started from the end of + * OS partition to the end of flash. + */ + if (addr >= uf_start && addr < uf_end) { + up_progmem_write_disabledcache(addr, buf, count); + return 0; + } + + int pagesize; + int remain = count; + + pagesize = S5JS100_FLASH_PAGE_SIZE; + + g_sem->try_acquire(); + while (remain) { + int tmp = remain; + + if (tmp > pagesize) { + tmp = pagesize; + } + + s5js100_sflash_disable_wp(); + + /* Load and write data */ + local_memcpy((void *)addr, buf, tmp); + + /* Flush cache */ + clean_invalidate_dcache_by_addr((uint32_t *)(addr & CACHE_LINE_MASK), tmp + CACHE_LINE_SIZE); + + s5js100_sflash_enable_wp(); + + buf += tmp; + addr += tmp; + remain -= tmp; + } + g_sem->release(); + + return 0; +} + +static int _is_erased(unsigned int address, int size) +{ + unsigned int *p = (unsigned int *)address; + + while (size > 0) { + if (*p != 0xFFFFFFFF) { + return 0; + } else { + p++; + size -= 4; + } + } + + return 1; +} + +int up_progmem_erasepage(unsigned int page) +{ + int addr; + + if (page >= up_progmem_npages()) { + return -1; + } + + addr = up_progmem_getaddress(page); + /* skip erased block */ + if (_is_erased(addr, up_progmem_blocksize())) { + return 0; + } + + g_sem->try_acquire(); + //s5js100_flash_take_sem(); + + s5js100_sflash_disable_wp(); + + /* Set sector address and then send erase command */ + putreg32(addr - S5JS100_FLASH_PADDR, S5JS100_SFLASH_ERASE_ADDRESS); + putreg8(0xff, S5JS100_SFLASH_SE); + + /* Wait for the completion */ + while (s5js100_sflash_read_status() & 0x1) { + }; + + /* Invalidate cache */ + invalidate_dcache_by_addr((uint32_t *)(addr & CACHE_LINE_MASK)/* + S5JS100_FLASH_PADDR*/, up_progmem_blocksize()); + s5js100_sflash_enable_wp(); + + + g_sem->release(); + + return 0; +} + + +unsigned int up_progmem_write(unsigned int addr, const void *buf, unsigned int count) +{ + return sflash_write(addr, (unsigned char *)buf, count); +} + + +int sflash_erase(unsigned int address) +{ + int page; + page = up_progmem_getpage(address); + return up_progmem_erasepage(page); +} + +#define ENV_MAX 20 +struct _env_list { + char env_name[11]; + char env_val[41]; +} env_list[ENV_MAX]; + +#define BOOTARG_VAL_OFFSET 0x40 +#define BOOTARG_VAL_MAX_SIZE 0x40 +void sflash_os_env_parser(void) +{ + char *env_addr, *ptr; + int argc = 0; + char buf[4096]; + uint32_t env_offset; + + if (s5js100_sflash_read_capacity() == 8 * 1024 * 1024) { + env_offset = S5JS100_OS_ENV_OFFSET_8MB; + } + + if (s5js100_sflash_read_capacity() == 16 * 1024 * 1024) { + env_offset = S5JS100_OS_ENV_OFFSET_16MB; + } + + env_addr = (char *)(S5JS100_FLASH_PADDR + env_offset + BOOTARG_VAL_OFFSET); + memcpy(buf, env_addr, 4 * 1024); + + ptr = buf; + + while (argc < ENV_MAX) { + char *arg = ptr; + int i = 0, j = 1; //j from '=' + + if (*ptr == 0xFF || *ptr == 0) { + ptr += BOOTARG_VAL_OFFSET;//strtok(NULL, "\n\r\t ,"); + argc++; + continue; + } + while (*(arg + i) != '=') { + if (*(arg + i) == 0xFF || i >= 10) { + return; + } + i++; + } + *(arg + i) = '\0'; + + strcpy(env_list[argc].env_name, arg); + + while (j < BOOTARG_VAL_MAX_SIZE - i) { + if (*(arg + i + j) == 0xFF || *(arg + i + j) == 0) { + break; + } + j++; + } + *(arg + i + j) = '\0'; + + strcpy(env_list[argc++].env_val, arg + i + 1); + + ptr += BOOTARG_VAL_OFFSET;//strtok(NULL, "\n\r\t ,"); + } + +} + +char *get_env(const char *name) +{ + int i; + for (i = 0; i < ENV_MAX; i++) { + if (!strcmp(name, env_list[i].env_name)) { + return env_list[i].env_val; + } + } + return 0; +} + + +#ifdef DEVICE_FLASH +/*************** flash_hal API ********************/ +/* hal/flash_api.h */ +int32_t flash_init(flash_t *obj) +{ + printf("%s\n\r", __func__); + SFlash_DriverInitialize(); + return 0; +} + +int32_t flash_free(flash_t *obj) +{ + printf("%s\n\r", __func__); + return 0; +} + +uint32_t flash_get_page_size(const flash_t *info) +{ +// printf("%s, PAGE[1B]\n\r", __func__); + return 4; /*S5JS100_FLASH_PAGE_SIZE*/ //byte program +} + +uint32_t flash_get_sector_size(const flash_t *info, uint32_t addr) +{ +// printf("%s addr[0x%x], size[0x%x]\n\r", __func__, addr, S5JS100_FLASH_BLOCK_SIZE); + return up_progmem_blocksize(); //4KB +} + +uint32_t flash_get_start_address(const flash_t *info) +{ +// printf("%s addr[0x%x]\n\r", __func__, S5JS100_FLASH_FS_PADDR); + return S5JS100_FLASH_FS_PADDR; +} + +uint32_t flash_get_size(const flash_t *info) +{ +// printf("%s size[0x%x]\n\r", __func__, S5JS100_FLASH_FS_SIZE); + return S5JS100_FLASH_FS_SIZE; +} + +int32_t flash_program_page(flash_t *obj, uint32_t addr, const uint8_t *data, uint32_t size) +{ +// printf("\n\rW\r\n"); + if (addr > S5JS100_FLASH_PADDR) { + printf("%s FLASH, addr[0x%x], size[%d]\n\r", __func__, addr, size); + return sflash_write(addr, (unsigned char *)data, size); + } else { +// printf("%s, addr[0x%x], size[%d]\n\r", __func__, addr, size); +// sflash_write(0x4086A000+flash_idx, (unsigned char *)data, size); //Write Test +// printf("\n\rWRITE[0x%x], [0x%x]", addr, 0x4086A000+flash_idx); + local_memcpy((void *)addr, (void *)data, size); + return 0; + } +} +uint8_t flash_get_erase_value(const flash_t *obj) +{ + (void)obj; +// printf("%s\n\r", __func__); + return 0xFF; +} + +int32_t flash_erase_sector(flash_t *obj, uint32_t addr) +{ +// printf("\n\rE\n\r"); + if (addr > S5JS100_FLASH_PADDR) { + printf("%s FLASH addr[0x%x]\n\r", __func__, addr); + return sflash_erase(addr); + } else { +// printf("%s addr[0x%x]\n\r", __func__, addr); +// printf("\n\r[[ERASE]]\n\r"); //Erase Test +// sflash_erase(0x4086A000); + memset((void *)addr, 0xFFFFFFFF, 4096); + return 0; + } +} +#endif + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.h new file mode 100755 index 0000000000..05662e81a0 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/sflash_api.h @@ -0,0 +1,226 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 _SFLASH_DRV_H +#define _SFLASH_DRV_H + +//#include "fcache_api.h" + +#ifdef __cplusplus + +extern "C" { +#else +#include +#endif +#define S5JS100_FLASH_PAGE_SIZE 256 +#define S5JS100_FLASH_BLOCK_SIZE 4096 +#define S5JS100_FLASH_PADDR (0x40000000) + + +#define S5JS100_FLASH_FS_PADDR 0x40EF5000 +#define S5JS100_FLASH_FS_SIZE 256*1024 + + +#define S5JS100_FLASH_SIZE (16 * 1024 * 1024) +#define S5JS100_OS_ENV_OFFSET_16MB (0x2E000) +#define S5JS100_OS_ENV_OFFSET_8MB (0x3B000) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#define S5JS100_SFLASH_BASE (0x85020000) +#define S5JS100_SFLASH_SFCON ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0004)) +#define S5JS100_SFLASH_ERASE_ADDRESS ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0010)) +#define S5JS100_SFLASH_USER_COMMAND ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0018)) +#define S5JS100_SFLASH_COMMAND1 ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x001C)) +#define S5JS100_SFLASH_COMMAND2 ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0020)) +#define S5JS100_SFLASH_COMMAND3 ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0024)) +#define S5JS100_SFLASH_COMMAND4 ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0028)) +#define S5JS100_SFLASH_COMMAND5 ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x002C)) +#define S5JS100_SFLASH_USER_INSTRUCTION ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0059)) +#define S5JS100_SFLASH_SE ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x005E)) +#define S5JS100_SFLASH_IO_MODE ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0074)) +#define S5JS100_SFLASH_PERF_MODE ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x0078)) +#define S5JS100_SFLASH_RDID ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00AC)) +#define S5JS100_SFLASH_BE ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00BE)) +#define S5JS100_SFLASH_CE ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00CE)) +#define S5JS100_SFLASH_RDSR ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00DC)) +#define S5JS100_SFLASH_WRDI ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00DD)) +#define S5JS100_SFLASH_WRSR ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00E0)) +#define S5JS100_SFLASH_WREN ((volatile unsigned int *)(S5JS100_SFLASH_BASE + 0x00EE)) +/* Register Bitfield Definitions ********************************************/ +/* Control Register */ +#define SFLASH_SFCON_WP_SHIFT 31 +#define SFLASH_SFCON_WP_MASK (0x1 << SFLASH_SFCON_WP_SHIFT) +#define SFLASH_SFCON_WP_ENABLE (0x0 << SFLASH_SFCON_WP_SHIFT) +#define SFLASH_SFCON_WP_DISABLE (0x1 << SFLASH_SFCON_WP_SHIFT) + +#define SFLASH_SFCON_MEMORY_VENDOR_SHIFT 16 +#define SFLASH_SFCON_MEMORY_VENDOR_MASK (0x3f << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) +#define SFLASH_SFCON_MEMORY_VENDOR_WINBOND (0x20 << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) +#define SFLASH_SFCON_MEMORY_VENDOR_MACRONIX (0x10 << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) +#define SFLASH_SFCON_MEMORY_VENDOR_ATMEL (0x08 << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) +#define SFLASH_SFCON_MEMORY_VENDOR_AMD (0x04 << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) +#define SFLASH_SFCON_MEMORY_VENDOR_STMICRO (0x02 << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) +#define SFLASH_SFCON_MEMORY_VENDOR_SST (0x01 << SFLASH_SFCON_MEMORY_VENDOR_SHIFT) + +#define SFLASH_SFCON_PAGE_EN_SHIFT 15 +#define SFLASH_SFCON_PAGE_EN_MASK (0x1 << SFLASH_SFCON_PAGE_EN_SHIFT) +#define SFLASH_SFCON_PAGE_EN_BYTEPROG (0x0 << SFLASH_SFCON_PAGE_EN_SHIFT) +#define SFLASH_SFCON_PAGE_EN_PAGEPROG (0x1 << SFLASH_SFCON_PAGE_EN_SHIFT) + +#define SFLASH_SFCON_PAGE_SHIFT 8 +#define SFLASH_SFCON_PAGE_MASK (0xf << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_4BYTES (0x0 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_8BYTES (0x1 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_16BYTES (0x2 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_32BYTES (0x3 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_64BYTES (0x4 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_128BYTES (0x5 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_256BYTES (0x6 << SFLASH_SFCON_PAGE_SHIFT) +#define SFLASH_SFCON_PAGE_RESERVED (0x7 << SFLASH_SFCON_PAGE_SHIFT) + +#define SFLASH_SFCON_HALF_DELAY_SHIFT 7 +#define SFLASH_SFCON_HALF_DELAY_MASK (0x1 << SFLASH_SFCON_HALF_DELAY_SHIFT) +#define SFLASH_SFCON_HALF_DELAY_OFF (0x0 << SFLASH_SFCON_HALF_DELAY_SHIFT) +#define SFLASH_SFCON_HALF_DELAY_ON (0x1 << SFLASH_SFCON_HALF_DELAY_SHIFT) + +#define SFLASH_SFCON_ERASE_WAIT_SHIFT 4 +#define SFLASH_SFCON_ERASE_WAIT_MASK (0x1 << SFLASH_SFCON_ERASE_WAIT_SHIFT) +#define SFLASH_SFCON_ERASE_WAIT_OFF (0x0 << SFLASH_SFCON_ERASE_WAIT_SHIFT) +#define SFLASH_SFCON_ERASE_WAIT_ON (0x1 << SFLASH_SFCON_ERASE_WAIT_SHIFT) + +#define SFLASH_SFCON_PRE_CHARGE_SHIFT 0 +#define SFLASH_SFCON_PRE_CHARGE_MASK (0xf << SFLASH_SFCON_PRE_CHARGE_SHIFT) + +/* Flash I/O Mode */ +#define SFLASH_IO_MODE_MASK 0xf +#define SFLASH_IO_MODE_READ 0x0 +#define SFLASH_IO_MODE_FAST_READ 0x1 +#define SFLASH_IO_MODE_DUAL_FAST_READ 0x2 +#define SFLASH_IO_MODE_QUAD_FAST_READ 0x4 + +/* Flash Performance Mode */ +#define SFLASH_PERF_MODE_MASK 0x8 +#define SFLASH_PERF_MODE_NORMAL 0x0 +#define SFLASH_PERF_MODE_DUAL_QUAD 0x8 + +#define SFLASH_DUMMY_DATA 0x1 +#define SFLASH_SECTOR_OFFSET (12) +#define SFLASH_BLOCK32K_OFFSET (15) +#define SFLASH_BLOCK64K_OFFSET (16) + +#define SFLASH_SIZE_64KB (1< 0x00FFFFFFU) { + //lint -e{904} "Return statement before end of function" + return (-1); + } + + // Set SysTick Interrupt Priority +#if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)) || \ + (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + SCB->SHPR[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + SCB->SHPR[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); +#elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0))) + SCB->SHP[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) + SCB->SHP[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); +#else +#error "Unknown ARM Core!" +#endif + /* + override systick clock source + NVIC_SYSTICK_CTRL_CLKSOURCE=1 : Use processor clock + NVIC_SYSTICK_CTRL_CLKSOURCE=0 : Use OSC clock + */ + + SysTick->CTRL = 0x10003;//SysTick_CTRL_COUNTFLAG_Msk | /*SysTick_CTRL_CLKSOURCE_Msk |*/ SysTick_CTRL_TICKINT_Msk; + SysTick->LOAD = load; +// SysTick->VAL = 0U; + + PendST = 0U; + + return (0); +} + +void OS_Tick_Enable(void) +{ + +} + +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /*Configure the SysTick to have interrupt in 1ms time basis*/ + HAL_SYSTICK_Config(SYSTICK_RELOAD); + + /*Configure the SysTick IRQ priority */ + //HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0); + + /* Return function status */ + return HAL_OK; +} + +#if defined ( __ICCARM__ ) +#define S5JS100_BOOTMEM_BASE 0x00000000 +extern uint32_t __vector_table; +extern uint32_t __Vectors_Size; +#elif defined (TOOLCHAIN_ARM_STD)/*__ARMCC_VERSION)*/ +#define S5JS100_BOOTMEM_BASE 0x00000000 +extern uint32_t __Vectors; +extern uint32_t __Vectors_Size; +#elif defined ( __GNUC__ ) +extern uint32_t _v_start; +extern uint32_t __vector_table; +extern uint32_t __vector_table_end; +extern uint32_t __isr_vector[]; +#endif +extern int cal_init(void); + +/* + * SystemCoreConfig(): Configure the System Core + */ +void SystemCoreConfig() +{ + + const uint32_t *src; + uint32_t *dest, size; + +#if defined ( __ICCARM__ ) + src = &__vector_table; + + dest = (uint32_t *)S5JS100_BOOTMEM_BASE; + size = (uint32_t)&__Vectors_Size; + + /* Move vector table to the right location. */ + for (src = &__vector_table, dest = (uint32_t *)S5JS100_BOOTMEM_BASE; dest < ((volatile unsigned int *)S5JS100_BOOTMEM_BASE + size);) { + *dest++ = *src++; + //*dest++ = *src++; + } + +#elif defined (TOOLCHAIN_ARM_STD)/*__ARMCC_VERSION)*/ + src = (uint32_t *)&__Vectors; + + dest = (uint32_t *)S5JS100_BOOTMEM_BASE; + size = (uint32_t)&__Vectors_Size; + + /* Move vector table to the right location. */ + for (dest = (uint32_t *)S5JS100_BOOTMEM_BASE; (uint32_t)dest < ((uint32_t)S5JS100_BOOTMEM_BASE + size);) { + *dest++ = *src++; + //*dest++ = *src++; + } +#elif defined ( __GNUC__ ) + src = __isr_vector; + dest = &_v_start; + size = (uint32_t)&__vector_table_end - (uint32_t)&__vector_table; + + /* Move vector table to the right location. */ + for (src = __isr_vector, dest = &_v_start; dest < (&_v_start + size);) { + *dest++ = *src++; + } +#endif + + cal_init(); + + HAL_InitTick(TICK_INT_PRIORITY); +} + +/* POWER MANAGEMENT */ + +/* + * SystemPowerConfig(): Configures the System Power Modes + */ +void SystemPowerConfig() +{ +} + +/* + * SystemPowerSuspend(): Enters in System Suspend + */ +void SystemPowerSuspend(power_mode_t mode) +{ + if (mode == POWER_MODE_DEEP_SLEEP) { + /* Enable deepsleep */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + /* Ensure effect of last store takes effect */ + __DSB(); + /* Enter sleep mode */ + __WFI(); + } else { + /* Enter sleep mode */ + __WFI(); + } +} + +/* + * SystemPowerResume(): Returns from System Suspend + */ +void SystemPowerResume(power_mode_t mode) +{ + if (mode == POWER_MODE_DEEP_SLEEP) { + /* Disable sleeponexit */ + SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; + /* Ensure effect of last store takes effect */ + __DSB(); + } +} + + +/* + * System config data storage functions + * Reserved as the data is not strictly persistent + */ + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_s5js100.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_s5js100.h new file mode 100644 index 0000000000..78c1d2a17f --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_s5js100.h @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 : system_core_s5js100.h + * @brief : System core configuration header + * @date : June 2019 + * + * @note : Add system mode + * + */ + +#ifndef SYSTEM_CORE_S5JS100_H +#define SYSTEM_CORE_S5JS100_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * SystemCoreConfig(): Configure the System Core + */ +void SystemCoreConfig(void); + +/* POWER MANAGEMENT */ +/* Power Mode Type Definition */ +typedef enum { + /* Sleep Power Mode */ + POWER_MODE_SLEEP = 0, + /* Deep Sleep Power Mode */ + POWER_MODE_DEEP_SLEEP = 1 +} power_mode_t; + +/* APB System Core Clocks */ +#define SYSTEM_CORE_TIMER0 (1 << 0) +#define SYSTEM_CORE_TIMER1 (1 << 1) +#define SYSTEM_CORE_DUALTIMER0 (1 << 2) +#define SYSTEM_CORE_UART0 (1 << 4) +#define SYSTEM_CORE_UART1 (1 << 5) +#define SYSTEM_CORE_I2C0 (1 << 7) +#define SYSTEM_CORE_WDOG (1 << 8) +#define SYSTEM_CORE_QSPI (1 << 11) +#define SYSTEM_CORE_SPI0 (1 << 12) +#define SYSTEM_CORE_SPI1 (1 << 13) +#define SYSTEM_CORE_I2C1 (1 << 14) +#define SYSTEM_CORE_TRNG (1 << 15) /* TRNG can not be a wakeup source */ + +/* + * SystemPowerConfig(): Configures the System Power Modes + */ +void SystemPowerConfig(void); + +/* + * SystemPowerSuspend(): Enters in System Suspend + */ +void SystemPowerSuspend(power_mode_t mode); + +/* + * SystemPowerResume(): Returns from System Suspend + */ +void SystemPowerResume(power_mode_t mode); + +/* + * Definitions for storing static configuration data in Beetle + * This is not strictly persistent data as it will get wiped out on chip erase. + * + * There are only read functions provided. + * No Write function to prevent accidental writes resulting in + * the system being non responsive. + * Use the Flash manual before trying to write anything in the last 4k. + */ +#define SYSTEM_CORE_CONFIG_DATA_SIZE (0x200) /* 512 bytes*/ + +typedef struct { + uint32_t BD_ADDR[2]; + + /*rest reserved*/ + uint32_t reserved[SYSTEM_CORE_CONFIG_DATA_SIZE - 2]; +} SystemCoreConfigData; + +/* + * __System_Config_GetBDAddr(): Address for the BLE device on the air. + */ +void __System_Config_GetBDAddr(uint8_t *addr, uint8_t len); + +#ifdef __cplusplus +} +#endif +#endif /* SYSTEM_CORE_S5JS100_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.c new file mode 100644 index 0000000000..3ecaf02cce --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +#include +#include +#include "system_core_version.h" + +#define REALLY_MAKE_STR(y) #y +#define MAKE_STR(x) REALLY_MAKE_STR(x) +#define SYSTEM_CORE_VERSION() (SYSTEM_CORE_PLATFORM ".SYSTEM.CORE." \ + MAKE_STR(SYSTEM_CORE_OS) \ + "." MAKE_STR(SYSTEM_CORE_VERSION_MAJOR) \ + "." MAKE_STR(SYSTEM_CORE_VERSION_MINOR) \ + "." MAKE_STR(SYSTEM_CORE_VERSION_PATCH) \ + " " SYSTEM_CORE_DATE \ + " " SYSTEM_CORE_TIME) + +/* Private Data */ +const char *system_core_version = SYSTEM_CORE_VERSION(); + +/* Get System Core Version */ +const char *SystemCoreGetVersion() +{ + return system_core_version; +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.h new file mode 100644 index 0000000000..5fb1301521 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_core_version.h @@ -0,0 +1,45 @@ +/* mbed Microcontroller Library + * Copyright (c) 2019 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SYSTEM_CORE_VERSION_H +#define SYSTEM_CORE_VERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Platform Name */ +#define SYSTEM_CORE_PLATFORM "SAMSUNG SIDK S5JS100 " + +/* OS Version */ +#define SYSTEM_CORE_OS 5 + +/* System Core Version */ +#define SYSTEM_CORE_VERSION_MAJOR 0 +#define SYSTEM_CORE_VERSION_MINOR 1 +#define SYSTEM_CORE_VERSION_PATCH 0 +#define SYSTEM_CORE_DATE __DATE__ +#define SYSTEM_CORE_TIME __TIME__ + +/* Get System Core Version */ +const char *SystemCoreGetVersion(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_CORE_VERSION_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.c new file mode 100644 index 0000000000..d721a0afcd --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.c @@ -0,0 +1,83 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 : system_s5js100.c + * @brief : System core configuration source code + * @date : June 2019 + * + * @note : fix chip dependent system clock + * + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + * Define clocks + *----------------------------------------------------------------------------*/ +#define __SYSTEM_CLOCK (198000000UL) + +/*---------------------------------------------------------------------------- + * Clock Variable definitions + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK; + +/*---------------------------------------------------------------------------- + * Clock functions + *----------------------------------------------------------------------------*/ +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK; +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System. + */ +void SystemInit(void) +{ + SystemCoreConfig(); +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.h new file mode 100644 index 0000000000..77ddd542d6 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/device/system_s5js100.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SYSTEM_SIDK_S5JS100_H +#define SYSTEM_SIDK_S5JS100_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit(void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_SIDK_S5JS100_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio.h new file mode 100644 index 0000000000..271e030e52 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio.h @@ -0,0 +1,261 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __ARCH_ARM_SRC_S5JS100_CHIP_S5JS100_GPIO_H__ +#define __ARCH_ARM_SRC_S5JS100_CHIP_S5JS100_GPIO_H__ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Bit-encoded input to s5js100_configgpio() */ +/* [02:00] */ +#define GPIO_FUNC_SHIFT (0) +#define GPIO_FUNC_MASK (0x7 << GPIO_FUNC_SHIFT) +#define GPIO_ALT0 (0x0 << GPIO_FUNC_SHIFT) +#define GPIO_ALT1 (0x1 << GPIO_FUNC_SHIFT) +#define GPIO_ALT2 (0x2 << GPIO_FUNC_SHIFT) +#define GPIO_ALT3 (0x3 << GPIO_FUNC_SHIFT) +#define GPIO_ALT4 (0x4 << GPIO_FUNC_SHIFT) +#define GPIO_ALT5 (0x5 << GPIO_FUNC_SHIFT) +#define GPIO_ALT6 (0x6 << GPIO_FUNC_SHIFT) +/* [03:03] */ +#define GPIO_INT_SHIFT 3 +#define GPIO_INT_MASK (0x1 << GPIO_INT_SHIFT) +#define GPIO_EINT (0x1 << GPIO_INT_SHIFT) +/* [06:04] */ +#define GPIO_EINT_SHIFT 4 +#define GPIO_EINT_MASK (0x7 << GPIO_EINT_SHIFT) +#define GPIO_EINT_LOW (0x0 << GPIO_EINT_SHIFT) +#define GPIO_EINT_HIGH (0x1 << GPIO_EINT_SHIFT) +#define GPIO_EINT_FALLING_EDGE (0x2 << GPIO_EINT_SHIFT) +#define GPIO_EINT_RISING_EDGE (0x3 << GPIO_EINT_SHIFT) +#define GPIO_EINT_BOTH_EDGE (0x4 << GPIO_EINT_SHIFT) +/* [07:07] */ +#define GPIO_VALUE_SHIFT 7 +#define GPIO_VALUE_MASK (0x1 << GPIO_VALUE_SHIFT) +#define GPIO_VALUE_ZERO (0x0 << GPIO_VALUE_SHIFT) +#define GPIO_VALUE_ONE (0x1 << GPIO_VALUE_SHIFT) +/* [10:08] */ +#define GPIO_DRVSTR_SHIFT 8 +#define GPIO_DRVSTR_MASK (0x7 << GPIO_DRVSTR_SHIFT) +#define GPIO_FAST1X (0x0 << GPIO_DRVSTR_SHIFT) +#define GPIO_FAST2X (0x1 << GPIO_DRVSTR_SHIFT) +#define GPIO_FAST3X (0x2 << GPIO_DRVSTR_SHIFT) +#define GPIO_FAST4X (0x3 << GPIO_DRVSTR_SHIFT) +#define GPIO_SLOW1X (0x4 << GPIO_DRVSTR_SHIFT) +#define GPIO_SLOW2X (0x5 << GPIO_DRVSTR_SHIFT) +#define GPIO_SLOW3X (0x6 << GPIO_DRVSTR_SHIFT) +#define GPIO_SLOW4X (0x7 << GPIO_DRVSTR_SHIFT) +/* [12:11] */ +#define GPIO_PUPD_SHIFT 11 +#define GPIO_PUPD_MASK (0x3 << GPIO_PUPD_SHIFT) +#define GPIO_FLOAT (0x0 << GPIO_PUPD_SHIFT) +#define GPIO_RESERVED (0x1 << GPIO_PUPD_SHIFT) +#define GPIO_PULLDOWN (0x2 << GPIO_PUPD_SHIFT) +#define GPIO_PULLUP (0x3 << GPIO_PUPD_SHIFT) +/* [13:13] */ +#define GPIO_INPUT_SHIFT 13 +#define GPIO_INPUT_MASK (0x1 << GPIO_INPUT_SHIFT) +#define GPIO_INPUT (0x1 << GPIO_INPUT_SHIFT) +/* [14:14] */ +#define GPIO_OUTPUT_SHIFT 14 +#define GPIO_OUTPUT_MASK (0x1 << GPIO_OUTPUT_SHIFT) +#define GPIO_OUTPUT (0x1 << GPIO_OUTPUT_SHIFT) +/* [22:16] */ +#define GPIO_PIN_SHIFT 16 +#define GPIO_PIN_MASK (0x7F << GPIO_PIN_SHIFT) +/* [28:23] */ +#define GPIO_IRQ_SHIFT 23 +#define GPIO_IRQ_MASK (0x3F << GPIO_IRQ_SHIFT) + +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN32 (32 << GPIO_PIN_SHIFT) +#define GPIO_PIN33 (33 << GPIO_PIN_SHIFT) +#define GPIO_PIN34 (34 << GPIO_PIN_SHIFT) +#define GPIO_PIN35 (35 << GPIO_PIN_SHIFT) +#define GPIO_PIN36 (36 << GPIO_PIN_SHIFT) +#define GPIO_PIN37 (37 << GPIO_PIN_SHIFT) +#define GPIO_PIN38 (38 << GPIO_PIN_SHIFT) +#define GPIO_PIN39 (39 << GPIO_PIN_SHIFT) +#define GPIO_PIN40 (40 << GPIO_PIN_SHIFT) +#define GPIO_PIN41 (41 << GPIO_PIN_SHIFT) +#define GPIO_PIN42 (42 << GPIO_PIN_SHIFT) +#define GPIO_PIN43 (43 << GPIO_PIN_SHIFT) +#define GPIO_PIN44 (44 << GPIO_PIN_SHIFT) +#define GPIO_PIN45 (45 << GPIO_PIN_SHIFT) +#define GPIO_PIN46 (46 << GPIO_PIN_SHIFT) +#define GPIO_PIN47 (47 << GPIO_PIN_SHIFT) +#define GPIO_PIN48 (48 << GPIO_PIN_SHIFT) +#define GPIO_PIN49 (49 << GPIO_PIN_SHIFT) +#define GPIO_PIN50 (50 << GPIO_PIN_SHIFT) +#define GPIO_PIN51 (51 << GPIO_PIN_SHIFT) +#define GPIO_PIN52 (52 << GPIO_PIN_SHIFT) +#define GPIO_PIN53 (53 << GPIO_PIN_SHIFT) +#define GPIO_PIN54 (54 << GPIO_PIN_SHIFT) +#define GPIO_PIN55 (55 << GPIO_PIN_SHIFT) +#define GPIO_PIN56 (56 << GPIO_PIN_SHIFT) +#define GPIO_PIN57 (57 << GPIO_PIN_SHIFT) +#define GPIO_PIN58 (58 << GPIO_PIN_SHIFT) +#define GPIO_PIN59 (59 << GPIO_PIN_SHIFT) +#define GPIO_PIN60 (60 << GPIO_PIN_SHIFT) +#define GPIO_PIN61 (61 << GPIO_PIN_SHIFT) +#define GPIO_PIN62 (62 << GPIO_PIN_SHIFT) +#define GPIO_PIN63 (63 << GPIO_PIN_SHIFT) +#define GPIO_PIN64 (64 << GPIO_PIN_SHIFT) +#define GPIO_PIN65 (65 << GPIO_PIN_SHIFT) +#define GPIO_PIN66 (66 << GPIO_PIN_SHIFT) +#define GPIO_PIN67 (67 << GPIO_PIN_SHIFT) +#define GPIO_PIN68 (68 << GPIO_PIN_SHIFT) +#define GPIO_PIN69 (69 << GPIO_PIN_SHIFT) +#define GPIO_PIN70 (70 << GPIO_PIN_SHIFT) +#define GPIO_PIN71 (71 << GPIO_PIN_SHIFT) +#define GPIO_PIN72 (72 << GPIO_PIN_SHIFT) + +#define S5JS100_GPIO_NPORTS 73 +#define GPIO_BASE (0x85026000) +#define TOP_MUX_BASE (0x82021000) +#define GPIO_MSG 1 +#define GPIO_INT 0 + +/* Register addresses *******************************************************/ + +#define GPIO_CPU_OFFSET (0x0020) +#define GPIO_CON_REG (GPIO_BASE + 0x0000) +#define GPIO_OUT_REG (GPIO_BASE + 0x0100) +#define GPIO_IN_REG (GPIO_BASE + 0x0200) +#define GPIO_INT_MASK_REG (GPIO_BASE + 0x0300) +#define GPIO_INT_PEND_CLR_REG (GPIO_BASE + 0x0400) +#define GPIO_INT_POL_REG (GPIO_BASE + 0x0500) +#define GPIO_INT_METHOD_REG (GPIO_BASE + 0x0600) +#define GPIO_INT_BOTH_REG (GPIO_BASE + 0x0700) +#define GPIO_ICG_REG (GPIO_BASE + 0x0800) +#define GPIO_CPU_SEL_REG (GPIO_BASE + 0x0900) + +enum gpio_int_type_ { + LEVEL_LOW, + LEVEL_HIGH, + NEG_EDGE, + POS_EDGE, + BOTH_EDGE, +}; + +enum pull_up_down_ { + GPIO_PUPD_DIS = 0, + GPIO_PULL_DOWN = 2, // 0b10 (enable + down) + GPIO_PULL_UP = 3, // 0b11 (enable + up) +}; + +enum drive_strength_ { + DS_2mA = 0, + DS_4mA, + DS_8mA, + DS_12mA, +}; + +enum in_enable_ { + IN_DIS = 0, + IN_EN, +}; + +enum out_enable_ { + OUT_DIS = 0, + OUT_EN, +}; + +enum bitpos_topmux_ { + BITPOS_FUNC = 0, + BITPOS_DS = 8, //drive strengh + BITPOS_SR = 10, //slew rate + BITPOS_PUPD = 11, + BITPOS_IE = 13, //input enable/disable + BITPOS_OE = 14, //output enable/disable +}; + +enum nmux_func_ { + NMUX_SEL_0 = 0, + NMUX_SEL_1 = 1, + NMUX_SEL_2 = 2, + NMUX_SEL_3 = 3, + NMUX_SEL_4 = 4, + NMUX_SEL_5 = 5, + NMUX_SEL_6 = 6, + GPIO_GPIO = 7, +}; + +enum gpio_id_ { + GPIO0 = 0, + GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, + GPIO11, GPIO12, GPIO13, GPIO14, GPIO15, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, + GPIO21, GPIO22, GPIO23, GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30, + GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, GPIO47, GPIO48, GPIO49, GPIO50, + GPIO51, GPIO52, GPIO53, GPIO54, GPIO55, GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, + GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO_MAX, +}; + + +// function to enable the GPIO pin +struct tmux_range_ { + uint16_t addr; + uint8_t start_num; + uint8_t end_num; +}; + +#ifdef __cplusplus +extern "C" { +#endif +int s5js100_configgpio(uint32_t cfgset); +void gpio_set_func(enum gpio_id_ id, enum nmux_func_ func); +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_api.c new file mode 100755 index 0000000000..f0a1e01f5c --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_api.c @@ -0,0 +1,357 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "gpio_api.h" +#include "pinmap.h" +#include "gpio.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +// BIT MASK +#define MASK_1_BIT (0x00000001) +#define MASK_2_BIT (0x00000003) +#define MASK_3_BIT (0x00000007) +#define MASK_4_BIT (0x0000000F) +#define MASK_5_BIT (0x0000001F) +#define MASK_6_BIT (0x0000003F) +#define MASK_7_BIT (0x0000007F) + +#define SetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + putreg32((getreg32(uAddr) & ~((uMaskValue)<<(uBaseBit))) | (((uMaskValue)&(uSetValue))<<(uBaseBit)), uAddr) +#define GetBits(uAddr, uBaseBit, uMaskValue) \ + ((getreg32(uAddr)>>(uBaseBit))&(uMaskValue)) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +int gpio_pin_mode(PinName pin, PinMode mode); +uint32_t get_tmux_addr(enum gpio_id_ id) +{ + uint32_t i; + uint32_t offset; + const struct tmux_range_ tmux_range[] = { + // addr start end + {0x03C, 24, 72}, + {0x100, 0, 23}, + }; + + offset = 0; + + for (i = 0; i < ARRAY_SIZE(tmux_range); i++) { + if ((id >= tmux_range[i].start_num) && (id <= tmux_range[i].end_num)) { + offset = tmux_range[i].addr + ((id - tmux_range[i].start_num) * 4); + break; + } + } + + return (TOP_MUX_BASE + offset); +} + +void gpio_set_input_enable(enum gpio_id_ id, enum in_enable_ inen) +{ + uint32_t addr; + + addr = get_tmux_addr(id); + SetBits(addr, BITPOS_OE, MASK_1_BIT, OUT_DIS); + SetBits(addr, BITPOS_IE, MASK_1_BIT, inen); +} + +void gpio_set_func(enum gpio_id_ id, enum nmux_func_ func) +{ + uint32_t addr; + + addr = get_tmux_addr(id); + SetBits(addr, BITPOS_FUNC, MASK_3_BIT, func); +} + +void gpio_set_pupd(enum gpio_id_ id, enum pull_up_down_ pupd) +{ + uint32_t addr; + + addr = get_tmux_addr(id); + if (pupd == GPIO_PUPD_DIS) { + SetBits(addr, BITPOS_PUPD + 1, MASK_1_BIT, pupd); + } else { + SetBits(addr, BITPOS_PUPD, MASK_2_BIT, pupd); + } +} + +void gpio_set_ds(enum gpio_id_ id, enum drive_strength_ ds) +{ + uint32_t addr; + + addr = get_tmux_addr(id); + SetBits(addr, BITPOS_DS, MASK_2_BIT, ds); +} + +void s5js100_setdrv(uint32_t cfgset) +{ + uint32_t ds; + uint32_t pin; + /* CAVEAT: GPIO_FAST|SLOWXXX is compatible with GPIO_DRV_XXX */ + ds = (cfgset & GPIO_DRVSTR_MASK) >> GPIO_DRVSTR_SHIFT; + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + gpio_set_ds(pin, ds); +} + +void s5js100_pullup(uint32_t cfgset) +{ + uint32_t pin; + uint32_t pupd; + + /* CAVEAT: GPIO_PUPD_XXX is compatible with GPIO_PUD_XXX */ + pupd = (cfgset & GPIO_PUPD_MASK) >> GPIO_PUPD_SHIFT; + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + gpio_set_pupd(pin, pupd); +} + +void s5js100_setintedge(unsigned int pin, int edge) +{ + uint32_t group; + uint32_t addr; + uint32_t bitpos; + + group = pin >> 5; //group = 0, 1, + addr = group << 2; // addr = 0x0, 0x4, + bitpos = pin & 0x1F; + + switch (edge) { + case LEVEL_LOW: + putreg32(getreg32(GPIO_INT_METHOD_REG + addr) | (1 << bitpos), GPIO_INT_METHOD_REG + addr); + putreg32(getreg32(GPIO_INT_POL_REG + addr) & ~(1 << bitpos), GPIO_INT_POL_REG + addr); + break; + case LEVEL_HIGH: + putreg32(getreg32(GPIO_INT_METHOD_REG + addr) | (1 << bitpos), GPIO_INT_METHOD_REG + addr); + putreg32(getreg32(GPIO_INT_POL_REG + addr) | (1 << bitpos), GPIO_INT_POL_REG + addr); + break; + case NEG_EDGE: + putreg32(getreg32(GPIO_INT_METHOD_REG + addr) & ~(1 << bitpos), GPIO_INT_METHOD_REG + addr); + putreg32(getreg32(GPIO_INT_BOTH_REG + addr) & ~(1 << bitpos), GPIO_INT_BOTH_REG + addr); + putreg32(getreg32(GPIO_INT_POL_REG + addr) & ~(1 << bitpos), GPIO_INT_POL_REG + addr); + //gpio_set_pupd(pin, GPIO_PULL_UP); + break; + case POS_EDGE: + putreg32(getreg32(GPIO_INT_METHOD_REG + addr) & ~(1 << bitpos), GPIO_INT_METHOD_REG + addr); + putreg32(getreg32(GPIO_INT_BOTH_REG + addr) & ~(1 << bitpos), GPIO_INT_BOTH_REG + addr); + putreg32(getreg32(GPIO_INT_POL_REG + addr) | (1 << bitpos), GPIO_INT_POL_REG + addr); + //gpio_set_pupd(pin, GPIO_PULL_DOWN); + break; + case BOTH_EDGE: + putreg32(getreg32(GPIO_INT_METHOD_REG + addr) & ~(1 << bitpos), GPIO_INT_METHOD_REG + addr); + putreg32(getreg32(GPIO_INT_BOTH_REG + addr) | (1 << bitpos), GPIO_INT_BOTH_REG + addr); + break; + default: + break; + } +} + +void s5js100_setintmask(unsigned int pin, int mask) +{ + uint32_t group; + uint32_t addr; + uint32_t bitpos; + group = pin >> 5; //group = 0, 1, + addr = group << 2; // addr = 0x0, 0x4, + bitpos = pin & 0x1F; + + if (mask) { + putreg32(getreg32(GPIO_INT_MASK_REG + addr) | (0 << bitpos), GPIO_INT_MASK_REG + addr); // int disable + } else { + putreg32(getreg32(GPIO_INT_MASK_REG + addr) | (1 << bitpos), GPIO_INT_MASK_REG + addr); // int enable + } + /* workaround, eint first is set pended if counter part has GPIO output */ + putreg32(getreg32(GPIO_INT_PEND_CLR_REG + addr) | (1 << bitpos), GPIO_INT_PEND_CLR_REG + addr); // pending clear +} + +uint32_t s5js100_get_intpin(unsigned int ch) +{ + uint32_t i; + uint32_t pend = getreg32(GPIO_INT_PEND_CLR_REG + (ch * 0x4)); + for (i = 0; i < 32; i++) { + if (pend & (0x1 << i)) { + return i + ch * 32; + } + } + + return -1; +} + + +int s5js100_configinput(uint32_t cfgset) +{ + uint32_t pin; + uint32_t addr, bitpos; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + gpio_set_func(pin, GPIO_GPIO); + + /* Set as input */ + addr = GPIO_BASE + ((pin >> 5) << 2); + bitpos = pin & 0x1F; + putreg32(getreg32(addr) | (1 << bitpos), addr); + gpio_set_input_enable(pin, IN_EN); + + /* Set pull-up/down */ + s5js100_pullup(cfgset); + + return 0; +} + +int s5js100_configalt(uint32_t cfgset) +{ + uint32_t pin; + uint32_t func; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + func = (cfgset & GPIO_FUNC_MASK) >> GPIO_FUNC_SHIFT; + gpio_set_func(pin, func); + + /* Set pull-up mode */ + s5js100_pullup(cfgset); + + /* Set drive strength */ + s5js100_setdrv(cfgset); + + return 0; +} + +int s5js100_configinterrupt(uint32_t cfgset, uint32_t nirq) +{ + uint32_t pin; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + if (cfgset & GPIO_EINT) { + /* + * First, configure the port as a generic input so that we have + * a known starting point and consistent behavior during the + * re-configuration. + */ + s5js100_configinput(cfgset); + + /* Then, just remember the rising/falling edge interrupt enabled */ + s5js100_setintedge(pin, (cfgset & GPIO_EINT_MASK) >> GPIO_EINT_SHIFT); + s5js100_setintmask(pin, 0); + + /* workaround gpio eint clear int in NVIC side */ + ///SetBits(0xE000E280, nirq - S5JS100_IRQ_FIRST, MASK_1_BIT, 0x1); + } else { + s5js100_setintmask(pin, 1); + } + + return 0; +} + + +int s5js100_configgpio(uint32_t cfgset) +{ + int ret = -1; + + ret = s5js100_configalt(cfgset); + + s5js100_configinterrupt(cfgset, (cfgset & GPIO_IRQ_MASK) >> GPIO_IRQ_SHIFT); + + return ret; +} + +void s5js100_gpio_clear_pending(uint32_t pincfg) +{ + uint32_t pin; + uint32_t group; + uint32_t addr; + uint32_t bitpos; + + pin = (pincfg & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + group = pin >> 5; //group = 0, 1, + addr = group << 2; // addr = 0x0, 0x4, + bitpos = pin & 0x1F; + + putreg32(getreg32(GPIO_INT_PEND_CLR_REG + addr) | (1 << bitpos), GPIO_INT_PEND_CLR_REG + addr); // pending clear + +} + +uint32_t gpio_set(PinName pin) +{ + int bit; + + bit = pin % 32; + return (1 << bit); +} + +void gpio_init(gpio_t *obj, PinName pin) +{ + int idx; + int bit; + + if (pin == NC || pin > P72) { + obj->reg_out = NULL; + obj->pin = NC; + return; + } + + idx = pin / 32; + bit = pin % 32; + + obj->pin = pin; + obj->mask = (1 << bit); + obj->reg_out = (unsigned int *)(GPIO_OUT_REG + (idx * 4)); + obj->reg_dir = (unsigned int *)(GPIO_CON_REG + (idx * 4)); + obj->reg_in = (unsigned int *)(GPIO_IN_REG + (idx * 4)); + if (pin >= P00 && pin <= P72) { + // Set GPIO pin set as GENERAL GPIO + s5js100_configgpio(GPIO_DEFAULT_CONFIG | pin << GPIO_PIN_SHIFT); + } + +} + +void gpio_mode(gpio_t *obj, PinMode mode) +{ + enum gpio_id_ id = (enum gpio_id_)obj->pin; + if (obj->reg_out == NULL) { + return; + } + //pin_mode(obj->pin, mode); + if (mode == PullUp) { + gpio_pin_mode(obj->pin, mode); + gpio_set_pupd(id, GPIO_PULL_UP); + } + if (mode == PullDown) { + gpio_pin_mode(obj->pin, mode); + gpio_set_pupd(id, GPIO_PULL_DOWN); + } +} + +void gpio_dir(gpio_t *obj, PinDirection direction) +{ + if (obj->reg_out == NULL) { + return; + } + if (direction == PIN_INPUT) { + *(obj->reg_dir) |= obj->mask; + } else if (direction == PIN_OUTPUT) { + *(obj->reg_dir) &= ~(obj->mask); + } +} + +int gpio_is_connected(const gpio_t *obj) +{ + if (obj->pin != (PinName)NC) { + return 1; + } else { + return 0; + } +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_irq_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_irq_api.c new file mode 100644 index 0000000000..031f6f931f --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_irq_api.c @@ -0,0 +1,265 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 : gpio_irq_api.c + * @brief : GPIO interrupt API source file + * @date : June 2019 + * + * @note : Add chip dependent feature and support up to 72 Pin + * + */ + +#include +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" +#include "mbed_trace.h" +#include "mbed_assert.h" + +#define TRACE_GROUP "GPIO" +#define PIN_NUM 73 +#define PININT_IRQ0 S5JS100_IRQ_GPIO_INTR0 +#define PININT_IRQ1 S5JS100_IRQ_GPIO_INTR1 +#define PININT_IRQ2 S5JS100_IRQ_GPIO_INTR2 + +struct pin_info { + uint8_t minor; + uint32_t ids; + uint32_t pincfg; + gpio_irq_event event; + +} pins[PIN_NUM] = { + {0, (uint32_t)NULL, GPIO_GPIO0, IRQ_NONE}, + {1, (uint32_t)NULL, GPIO_GPIO1, IRQ_NONE}, + {2, (uint32_t)NULL, GPIO_GPIO2, IRQ_NONE}, + {3, (uint32_t)NULL, GPIO_GPIO3, IRQ_NONE}, + {4, (uint32_t)NULL, GPIO_GPIO4, IRQ_NONE}, + {5, (uint32_t)NULL, GPIO_GPIO5, IRQ_NONE}, + {6, (uint32_t)NULL, GPIO_GPIO6, IRQ_NONE}, + {7, (uint32_t)NULL, GPIO_GPIO7, IRQ_NONE}, + {8, (uint32_t)NULL, GPIO_GPIO8, IRQ_NONE}, + {9, (uint32_t)NULL, GPIO_GPIO9, IRQ_NONE}, + {10, (uint32_t)NULL, GPIO_GPIO10, IRQ_NONE}, + {11, (uint32_t)NULL, GPIO_GPIO11, IRQ_NONE}, + {12, (uint32_t)NULL, GPIO_GPIO12, IRQ_NONE}, + {13, (uint32_t)NULL, GPIO_GPIO13, IRQ_NONE}, + {14, (uint32_t)NULL, GPIO_GPIO14, IRQ_NONE}, + {15, (uint32_t)NULL, GPIO_GPIO15, IRQ_NONE}, + {16, (uint32_t)NULL, GPIO_GPIO16, IRQ_NONE}, + {17, (uint32_t)NULL, GPIO_GPIO17, IRQ_NONE}, + {18, (uint32_t)NULL, GPIO_GPIO18, IRQ_NONE}, + {19, (uint32_t)NULL, GPIO_GPIO19, IRQ_NONE}, + {20, (uint32_t)NULL, GPIO_GPIO20, IRQ_NONE}, + {21, (uint32_t)NULL, GPIO_GPIO21, IRQ_NONE}, + {22, (uint32_t)NULL, GPIO_GPIO22, IRQ_NONE}, + {23, (uint32_t)NULL, GPIO_GPIO23, IRQ_NONE}, + {24, (uint32_t)NULL, GPIO_GPIO24, IRQ_NONE}, + {25, (uint32_t)NULL, GPIO_GPIO25, IRQ_NONE}, + {26, (uint32_t)NULL, GPIO_GPIO26, IRQ_NONE}, + {27, (uint32_t)NULL, GPIO_GPIO27, IRQ_NONE}, + {28, (uint32_t)NULL, GPIO_GPIO28, IRQ_NONE}, + {29, (uint32_t)NULL, GPIO_GPIO29, IRQ_NONE}, + {30, (uint32_t)NULL, GPIO_GPIO30, IRQ_NONE}, + {31, (uint32_t)NULL, GPIO_GPIO31, IRQ_NONE}, + {32, (uint32_t)NULL, GPIO_GPIO32, IRQ_NONE}, + {33, (uint32_t)NULL, GPIO_GPIO33, IRQ_NONE}, + {34, (uint32_t)NULL, GPIO_GPIO34, IRQ_NONE}, + {35, (uint32_t)NULL, GPIO_GPIO35, IRQ_NONE}, + {36, (uint32_t)NULL, GPIO_GPIO36, IRQ_NONE}, + {37, (uint32_t)NULL, GPIO_GPIO37, IRQ_NONE}, + {38, (uint32_t)NULL, GPIO_GPIO38, IRQ_NONE}, + {39, (uint32_t)NULL, GPIO_GPIO39, IRQ_NONE}, + {40, (uint32_t)NULL, GPIO_GPIO40, IRQ_NONE}, + {41, (uint32_t)NULL, GPIO_GPIO41, IRQ_NONE}, + {42, (uint32_t)NULL, GPIO_GPIO42, IRQ_NONE}, + {43, (uint32_t)NULL, GPIO_GPIO43, IRQ_NONE}, + {44, (uint32_t)NULL, GPIO_GPIO44, IRQ_NONE}, + {45, (uint32_t)NULL, GPIO_GPIO45, IRQ_NONE}, + {46, (uint32_t)NULL, GPIO_GPIO46, IRQ_NONE}, + {47, (uint32_t)NULL, GPIO_GPIO47, IRQ_NONE}, + {48, (uint32_t)NULL, GPIO_GPIO48, IRQ_NONE}, + {49, (uint32_t)NULL, GPIO_GPIO49, IRQ_NONE}, + {50, (uint32_t)NULL, GPIO_GPIO50, IRQ_NONE}, + {51, (uint32_t)NULL, GPIO_GPIO51, IRQ_NONE}, + {52, (uint32_t)NULL, GPIO_GPIO52, IRQ_NONE}, + {53, (uint32_t)NULL, GPIO_GPIO53, IRQ_NONE}, + {54, (uint32_t)NULL, GPIO_GPIO54, IRQ_NONE}, + {55, (uint32_t)NULL, GPIO_GPIO55, IRQ_NONE}, + {56, (uint32_t)NULL, GPIO_GPIO56, IRQ_NONE}, + {57, (uint32_t)NULL, GPIO_GPIO57, IRQ_NONE}, + {58, (uint32_t)NULL, GPIO_GPIO58, IRQ_NONE}, + {59, (uint32_t)NULL, GPIO_GPIO59, IRQ_NONE}, + {60, (uint32_t)NULL, GPIO_GPIO60, IRQ_NONE}, + {61, (uint32_t)NULL, GPIO_GPIO61, IRQ_NONE}, + {62, (uint32_t)NULL, GPIO_GPIO62, IRQ_NONE}, + {63, (uint32_t)NULL, GPIO_GPIO63, IRQ_NONE}, + {64, (uint32_t)NULL, GPIO_GPIO64, IRQ_NONE}, + {65, (uint32_t)NULL, GPIO_GPIO65, IRQ_NONE}, + {66, (uint32_t)NULL, GPIO_GPIO66, IRQ_NONE}, + {67, (uint32_t)NULL, GPIO_GPIO67, IRQ_NONE}, + {68, (uint32_t)NULL, GPIO_GPIO68, IRQ_NONE}, + {69, (uint32_t)NULL, GPIO_GPIO69, IRQ_NONE}, + {70, (uint32_t)NULL, GPIO_GPIO70, IRQ_NONE}, + {71, (uint32_t)NULL, GPIO_GPIO71, IRQ_NONE}, + {72, (uint32_t)NULL, GPIO_GPIO72, IRQ_NONE} +}; + +static gpio_irq_handler irq_handler; +uint32_t s5js100_get_intpin(unsigned int ch); +int s5js100_configinterrupt(uint32_t cfgset, uint32_t nirq); +void s5js100_gpio_clear_pending(uint32_t pincfg); + +static inline void handle_interrupt_in(uint32_t channel) +{ + int pin; + gpio_irq_event event; + + + pin = s5js100_get_intpin(channel); + if (pin < 0) { + return; + } + event = pins[pin].event; + MBED_ASSERT(pin < PIN_NUM); + + irq_handler(pins[pin].ids, pins[pin].event); //should be fixed by polarity +#if GPIO_EINT_DEBOUNCE + hw_delay_us(200000); +#endif + // toggle Interrupt condition + if (event == IRQ_RISE) { + pins[pin].pincfg &= ~(GPIO_EINT_MASK); + pins[pin].event = IRQ_FALL; + pins[pin].pincfg |= GPIO_EINT | GPIO_EINT_FALLING_EDGE; + } + if (event == IRQ_FALL) { + pins[pin].pincfg &= ~(GPIO_EINT_MASK); + pins[pin].event = IRQ_RISE; + pins[pin].pincfg |= GPIO_EINT | GPIO_EINT_RISING_EDGE; + } + + s5js100_configinterrupt(pins[pin].pincfg, (pins[pin].pincfg & GPIO_IRQ_MASK) >> GPIO_IRQ_SHIFT); + s5js100_gpio_clear_pending(pins[pin].pincfg); // +} + +void gpio0_irq(void) +{ + handle_interrupt_in(0); +} +void gpio1_irq(void) +{ + handle_interrupt_in(1); +} +void gpio2_irq(void) +{ + handle_interrupt_in(2); +} + +int gpio_pin_mode(PinName pin, PinMode mode) +{ + if (mode == PullUp) { + pins[pin].pincfg &= ~(GPIO_PUPD_MASK); + pins[pin].pincfg |= GPIO_PULLUP; + } + if (mode == PullDown) { + pins[pin].pincfg &= ~(GPIO_PUPD_MASK); + pins[pin].pincfg |= GPIO_PULLDOWN; + } + return 0; +} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, + gpio_irq_handler handler, uint32_t id) +{ + if (pin == NC) { + return -1; + } + MBED_ASSERT(pin < PIN_NUM); + + obj->ch = pin; + irq_handler = handler; + + // set handler for apps + pins[obj->ch].ids = id; + + NVIC_SetVector((IRQn_Type)(PININT_IRQ0), (uint32_t)gpio0_irq); + NVIC_SetVector((IRQn_Type)(PININT_IRQ1), (uint32_t)gpio1_irq); + NVIC_SetVector((IRQn_Type)(PININT_IRQ2), (uint32_t)gpio2_irq); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ0)); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ1)); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ2)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) +{ + +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) +{ + if (IRQ_RISE == event) { + //obj->flagR = (uint8_t)enable; +#if GPIO_EINT_LEVEL + pins[obj->ch].pincfg &= ~(GPIO_INT_MASK | GPIO_EINT_MASK | GPIO_PUPD_MASK); + pins[obj->ch].pincfg |= GPIO_EINT | GPIO_EINT_HIGH | GPIO_PULLDOWN; +#else + pins[obj->ch].pincfg |= GPIO_EINT | GPIO_EINT_RISING_EDGE; +#endif + pins[obj->ch].event = event; + } else { + //obj->flagF = (uint8_t)enable; +#if GPIO_EINT_LEVEL + pins[obj->ch].pincfg &= ~(GPIO_INT_MASK | GPIO_EINT_MASK | GPIO_PUPD_MASK); + pins[obj->ch].pincfg |= GPIO_EINT | GPIO_EINT_LOW | GPIO_PULLUP; +#else + pins[obj->ch].pincfg |= GPIO_EINT | GPIO_EINT_FALLING_EDGE; +#endif + pins[obj->ch].event = event; + } + s5js100_configgpio(pins[obj->ch].pincfg); +} + +void gpio_irq_enable(gpio_irq_t *obj) +{ + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ0 + (obj->ch / 32))); +} + +void gpio_irq_disable(gpio_irq_t *obj) +{ + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ0 + (obj->ch / 32))); +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_object.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_object.h new file mode 100644 index 0000000000..1d4dc86cfe --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/gpio_object.h @@ -0,0 +1,69 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + unsigned int mask; + + __IO unsigned int *reg_dir; + __IO unsigned int *reg_out; + __I unsigned int *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) +{ + if (obj->reg_out == (void *)0) { + return; + } + if (value == 1) { + *(obj->reg_out) |= (obj->mask); + } else if (value == 0) { + *(obj->reg_out) &= ~(obj->mask); + } +} + +static inline int gpio_read(gpio_t *obj) +{ + if (obj->reg_out == (void *)0) { + return 0; + } + if (*(obj->reg_dir) & obj->mask) { + return ((*(obj->reg_in) & obj->mask) ? 1 : 0); + } else { + return ((*(obj->reg_out) & obj->mask) ? 1 : 0); + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_api.c new file mode 100644 index 0000000000..a7ff65202f --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_api.c @@ -0,0 +1,875 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +#if DEVICE_I2C + +#include "i2c_api.h" +#include "i2c_def.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "mbed_wait_api.h" +/* States of a possibly combined I2C transfer */ +typedef enum i2c_transfer_state_t { + I2C_TRANSFER_SINGLE, /* Non combined transfer */ + I2C_TRANSFER_COMBINED_FIRST_MESSAGE, /* + * First message of a + * combined transfer + */ + I2C_TRANSFER_COMBINED_INTERMEDIATE_MESSAGE, /* + * Message in the middle + * of a combined + * transfer + */ + I2C_TRANSFER_COMBINED_LAST_MESSAGE, /* + * Last message of a combined + * transfer + */ +} i2c_transfer_state_t; + +/* + * Driver private data structure that should not be shared by multiple + * instances of the driver + * (same driver for multiple instances of the IP) + */ +typedef struct private_i2c_t { + /* State of a possibly combined ongoing i2c transfer */ + i2c_transfer_state_t transfer_state; +} private_i2c_t; + +struct i2c_msg_s { + uint16_t addr; /**< Slave address */ + uint16_t flags; /**< I2C flags; See I2C_M_* definitions */ +#ifdef CONFIG_I2C_USERIO + uint16_t length; /**< The length of buffer */ + uint8_t *buffer; /**< The Buffer for transferring message */ +#else + uint8_t *buffer; /**< The Buffer for transferring message */ + int length; /**< The length of buffer */ +#endif +}; + +#define S5JS100_DEFAULT_I2CXFER_CLOCK (100 * 1000) // 100KHz +#define S5JS100_DEFAULT_I2C_TIMEOUT 10000 +#define S5JS100_DEFAULT_I2CSLAVE_ADDR 0x69 +#define HSI2C_INT_XFER_DONE (HSI2C_INT_XFER_DONE_NOACK_MANUAL | HSI2C_INT_XFER_DONE_MANUAL) + +/* + * Retrieve the private data of the instance related to a given IP + */ +#if 0 +static private_i2c_t *get_i2c_private(i2c_t *obj) +{ + static private_i2c_t data0, data1; + /* + * Select which instance to give using the base + * address of registers + */ + switch ((intptr_t)obj->i2c) { + case I2C0_BASE: + return &data0; + case I2C1_BASE: + return &data1; + default: + error("i2c driver private data structure not found for this registers base address"); + return (void *)0; + } +} +#endif + +static const PinMap PinMap_I2C_SDA[] = { + {I2C_SDA, I2C_0, 0}, + {NC, NC, 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {I2C_SCL, I2C_0, 0}, + {NC, NC, 0} +}; +static void hsi2c_set_hs_timing(unsigned int base, unsigned int nClkDiv, + unsigned int tSTART_SU, unsigned int tSTART_HD, + unsigned int tSTOP_SU, unsigned int tSDA_SU, + unsigned int tDATA_SU, unsigned int tDATA_HD, + unsigned int tSCL_L, unsigned int tSCL_H, + unsigned int tSR_RELEASE) +{ + tSTART_SU &= 0xFF; + tSTART_HD &= 0xFF; + tSTOP_SU &= 0xFF; + putreg32(((tSTART_SU << 24) | (tSTART_HD << 16) | (tSTOP_SU << 8)), base + I2C_TIMING_HS1); + + tDATA_SU &= 0xFF; + tSCL_L &= 0xFF; + tSCL_H &= 0xFF; + putreg32(((tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0)), base + I2C_TIMING_HS2); + + nClkDiv &= 0xFF; + tSR_RELEASE &= 0xFF; + putreg32(((nClkDiv << 16) | (tSR_RELEASE << 0)), base + I2C_TIMING_HS3); + + tDATA_HD &= 0xFFFF; + putreg32(tDATA_HD, base + I2C_TIMING_SLA); + +} + +static void hsi2c_set_fs_timing(unsigned int base, unsigned int nClkDiv, + unsigned int tSTART_SU, unsigned int tSTART_HD, + unsigned int tSTOP_SU, unsigned int tDATA_SU, + unsigned int tDATA_HD, unsigned int tSCL_L, + unsigned int tSCL_H, unsigned int tSR_RELEASE) +{ + tSTART_SU &= 0xFF; + tSTART_HD &= 0xFF; + tSTOP_SU &= 0xFF; + putreg32(((tSTART_SU << 24) | (tSTART_HD << 16) | (tSTOP_SU << 8)), base + I2C_TIMING_FS1); + + tDATA_SU &= 0xFF; + tSCL_L &= 0xFF; + tSCL_H &= 0xFF; + putreg32(((tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0)), base + I2C_TIMING_FS2); + + nClkDiv &= 0xFF; + tSR_RELEASE &= 0xFF; + putreg32(((nClkDiv << 16) | (tSR_RELEASE << 0)), base + I2C_TIMING_FS3); + + tDATA_HD &= 0xFFFF; + putreg32(tDATA_HD, base + I2C_TIMING_SLA); +} + +static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk, + unsigned int nOpClk) +{ + unsigned int reg; + unsigned int nClkDiv; + uint32_t tFTL_CYCLE_SCL; + int i; + int uTemp0; + int uTemp1; + int uTemp2 = 0; + + reg = getreg32(base + I2C_CONF); + reg &= ~(0x7 << 13); + putreg32(reg, base + I2C_CONF); + + reg = getreg32(base + I2C_CONF); + reg &= ~(0x7 << 16); + putreg32(reg, base + I2C_CONF); + + tFTL_CYCLE_SCL = (getreg32(base + I2C_CONF) >> 16) & 0x7; + + uTemp0 = (float)(nPclk / nOpClk) - (tFTL_CYCLE_SCL + 3) * 2; + + for (i = 0; i < 256; i++) { + uTemp1 = (uTemp0 + ((tFTL_CYCLE_SCL + 3) % (i + 1)) * 2) / (i + 1); + if (uTemp1 < 512) { /* TSCL_L/H max is 512 / 2 */ + uTemp2 = uTemp1 - 2; + break; + } + } + + unsigned int tSCL_H; + nClkDiv = i; + if (nOpClk > I2C_SPEED_400KHZ) { + tSCL_H = ((uTemp2 + 10) / 3) - 5; + } else { + tSCL_H = uTemp2 / 2; + } + + unsigned int tSCL_L = uTemp2 - tSCL_H; + unsigned int tSTART_SU = tSCL_L; + unsigned int tSTART_HD = tSCL_L; + unsigned int tSTOP_SU = tSCL_L; + unsigned int tSDA_SU = tSCL_L; + unsigned int tDATA_SU = tSCL_L; + unsigned int tDATA_HD = tSCL_L / 2; + unsigned int tSR_RELEASE = uTemp2; + + if (nOpClk > I2C_SPEED_400KHZ) { + /* 400Khz setting for Extended ID */ + hsi2c_set_fs_timing(base, 1, 38, 38, 38, 19, 19, 38, 38, 76); + hsi2c_set_hs_timing(base, nClkDiv, tSTART_SU, tSTART_HD, tSTOP_SU, + tSDA_SU, tDATA_SU, tDATA_HD, tSCL_L, tSCL_H, tSR_RELEASE); + } else { + hsi2c_set_fs_timing(base, nClkDiv, tSTART_SU, tSTART_HD, tSTOP_SU, + tDATA_SU, tDATA_HD, tSCL_L, tSCL_H, tSR_RELEASE); + } +} + +static void hsi2c_conf(unsigned int base, unsigned int nOpClk) +{ + unsigned int val; + + val = getreg32(base + I2C_CONF); + val &= ~(3 << 30); + if (nOpClk > I2C_SPEED_400KHZ) { + val |= (1 << 29); + } else { + val &= ~(1 << 29); + } + putreg32(val, base + I2C_CONF); +} + +static void hsi2c_enable_int(unsigned int base, unsigned int bit) +{ + unsigned int val; + val = getreg32(base + INT_EN); + val |= bit; + putreg32(val, base + INT_EN); +} + +static void hsi2c_disable_int(unsigned int base, unsigned int bit) +{ + unsigned int val; + + val = getreg32(base + INT_EN); + val &= ~bit; + putreg32(val, base + INT_EN); +} + +static int hsi2c_manual_fast_init(i2c_t *obj) +{ + unsigned int val; + unsigned int base = obj->base; + + hsi2c_conf(base, obj->xfer_speed); + hsi2c_calculate_timing(base, obj->clock, obj->xfer_speed); + hsi2c_enable_int(base, HSI2C_INT_XFER_DONE_MANUAL | HSI2C_INT_XFER_DONE_NOACK_MANUAL); + + obj->initialized = 1; + + val = getreg32(base + I2C_CONF); + val &= ~((1 << 31) | (1 << 29)); + putreg32(val, base + I2C_CONF); + + hsi2c_enable_int(base, HSI2C_INT_XFER_DONE); + + return 0; +} + + +static void hsi2c_set_slave_addr(unsigned int base, unsigned short addr, + unsigned int is_master) +{ + unsigned int val; + + addr &= 0x3FF; + + val = getreg32(base + I2C_ADDR); + + if (is_master == 0) { + val &= ~0x3ff; + val |= addr; + } else { + val &= ~(0x3FF << 10); + val |= (addr << 10); + } + putreg32(val, base + I2C_ADDR); +} + +static int hsi2c_wait_xfer_done(i2c_t *obj) +{ + int val; + int timeout = obj->timeout; + unsigned int base = obj->base; + + while (timeout-- > 0) { + val = getreg32(base + INT_STAT) & HSI2C_INT_XFER_DONE_MANUAL; + if (val) { + putreg32(val, base + INT_STAT); + return (val == HSI2C_INT_XFER_DONE_MANUAL); + } + } + + return -1; +} + +static void hsi2c_start(i2c_t *obj) +{ + putreg32(0x88, I2C0_BASE + CTL); + + putreg32(I2C_START, obj->base + I2C_MANUAL_CMD); + + hsi2c_wait_xfer_done(obj); +} + +static void hsi2c_stop(i2c_t *obj) +{ + putreg32(I2C_STOP, obj->base + I2C_MANUAL_CMD); + + hsi2c_wait_xfer_done(obj); +} + +static void hsi2c_repstart(i2c_t *obj) +{ + putreg32(I2C_RESTART, obj->base + I2C_MANUAL_CMD); +} + +static int hsi2c_outb(i2c_t *obj, unsigned char data) +{ + unsigned int val; + int ret; + + val = ((unsigned int)data) << 24 | I2C_SEND_DATA; + putreg32(val, obj->base + I2C_MANUAL_CMD); + + ret = hsi2c_wait_xfer_done(obj); + + return ret; +} + +static int hsi2c_inb(i2c_t *obj, unsigned char is_ack) +{ + unsigned int val = I2C_READ_DATA; + unsigned char data; + int ret; + unsigned int base = obj->base; + + /* Looks awkward, but if I2C_RX_ACK is set, ACK is NOT generated */ + if (!is_ack) { + val |= I2C_RX_ACK; + } + putreg32(val, base + I2C_MANUAL_CMD); + + ret = hsi2c_wait_xfer_done(obj); + if (ret < 0) { + return ret; /* timeout */ + } + + data = (getreg32(base + I2C_MANUAL_CMD) >> 16) & 0xff; + + return data; +} + +static int sendbytes(i2c_t *obj, struct i2c_msg_s *msg) +{ + uint8_t *p = msg->buffer; + int count = msg->length; + int nak_ok = msg->flags & I2C_M_IGNORE_NAK; + int wrcount = 0, ret; + + while (count > 0) { + ret = hsi2c_outb(obj, *p); + if ((ret == 1) || ((ret == 0) && nak_ok)) { + count--; + p++; + wrcount++; + } else if (ret == 0) { + /* NAK from the slave */ + return -EIO; + } else { + /* Timeout */ + return ret; + } + } + + return wrcount; +} + +static int readbytes(i2c_t *obj, struct i2c_msg_s *msg) +{ + int val; + int rdcount = 0; + unsigned char *p = msg->buffer; + int count = msg->length; + + while (count > 0) { + val = hsi2c_inb(obj, (count > 1)); + if (val < 0) { + break; + } + + *p++ = val; + rdcount++; + count--; + } + + return rdcount; +} + +static int try_address(i2c_t *obj, unsigned char addr, int retries) +{ + int i, ret = 0; + + for (i = 0; i <= retries; i++) { + ret = hsi2c_outb(obj, addr); + if (ret == 1 || i == retries) { + break; + } + hsi2c_stop(obj); + wait_us(obj->timeout / 2); + hsi2c_start(obj); + } + + return ret; +} + +static int do_address(i2c_t *obj, struct i2c_msg_s *msg) +{ + unsigned short flags = msg->flags; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + unsigned char addr; + int ret; + int retries; + + retries = nak_ok ? 0 : obj->retries; + + if (flags & I2C_M_TEN) { + /* a 10-bit address in manual mode */ + addr = 0xf0 | ((msg->addr >> 7) & 0x06); + + ret = try_address(obj, addr, retries); + if ((ret != 1) && !nak_ok) { + return -ENXIO; + } + + /* the remaining 8 bit address */ + ret = hsi2c_outb(obj, msg->addr & 0xff); + if ((ret != 1) && !nak_ok) { + return -ENXIO; + } + + if (flags & I2C_M_READ) { + hsi2c_repstart(obj); + hsi2c_wait_xfer_done(obj); + addr |= 0x1; + ret = try_address(obj, addr, retries); + if ((ret != 1) && !nak_ok) { + return -EIO; + } + } + } else { + /* 7-bit address */ + addr = msg->addr << 1; + if (flags & I2C_M_READ) { + addr |= 0x1; + } + + ret = try_address(obj, addr, retries); + if ((ret != 1) && !nak_ok) { + return -ENXIO; + } + } + + return 0; +} +static void hsi2c_set_auto_config(unsigned int base, unsigned int stop, + unsigned int tx, unsigned int len) +{ + unsigned int val = getreg32(base + I2C_AUTO_CONF); + + if (stop) { + val |= (1 << 17); + } else { + val &= ~(1 << 17); + } + if (tx) { + val &= ~(1 << 16); + } else { + val |= (1 << 16); + } + + val &= ~0xFFFF; + val |= len; + putreg32(val, base + I2C_AUTO_CONF); +} + +static void hsi2c_set_trans_mode(unsigned int base, unsigned int master, + unsigned int tx) +{ + unsigned int val = getreg32(base + CTL); + + val |= (1 << 0); /* ctrl 0 bit write 1 */ + + if (master) { + val |= (1 << 3); + } else { + val &= ~(1 << 3); + } + + val &= ~(3 << 6); + if (tx) { + val |= (1 << 7); + } else { + val |= (1 << 6); + } + + putreg32(val, base + CTL); +} + +static void hsi2c_set_hwacg_mode(unsigned int base, unsigned int slave) +{ + unsigned int val = getreg32(base + CTL); + + val &= ~(0x3 << 24); + + if (slave) { + val |= (0x1 << 24); + } else { + val &= ~(0x1 << 24); + } + + putreg32(val, base + CTL); +} + +static void hsi2c_set_fifo_level(unsigned int base) +{ + putreg32(0x10013, base + FIFO_CTL); +} + + +static void hsi2c_master_setup(i2c_t *obj, unsigned int mode, + unsigned int speed, unsigned int slave_addr) +{ + if (obj->mode == I2C_POLLING) { + obj->xfer_speed = speed; + hsi2c_calculate_timing(obj->base, obj->clock, speed); + } +#ifdef CONFIG_S5JS100_I2C_INTERRUPT_MODE + else if (priv->mode == I2C_INTERRUPT) { + priv->master_test_data = (struct master_data *)malloc(sizeof(struct master_data)); + /* complete_init(&priv->master_test_data->done); */ + hsi2c_set_trans_mode(obj->base, 1, 1); /* set master mode */ + hsi2c_conf(obj->base, speed); + hsi2c_calculate_timing(obj->base, obj->clock, speed); + hsi2c_set_slave_addr(obj->base, slave_addr, 1); + hsi2c_set_auto_mode(obj->base); + hsi2c_set_fifo_level(obj->base); + } +#endif +} + +static void hsi2c_slave_setup(i2c_t *obj, unsigned int mode, + unsigned int speed, unsigned int slave_addr) +{ +// obj->i2c->slave_test_data = (struct slave_data *)malloc(sizeof(struct slave_data)); + + /* slave mode is only support slave mode */ + hsi2c_set_trans_mode(obj->base, 0, 0); /* set slave mode */ + + /*set hwacg for slave mode */ + hsi2c_set_hwacg_mode(obj->base, 1); + + hsi2c_conf(obj->base, speed); + hsi2c_calculate_timing(obj->base, obj->clock, speed); + hsi2c_set_slave_addr(obj->base, slave_addr, 0); + + hsi2c_disable_int(obj->base, HSI2C_INT_ALL); + hsi2c_enable_int(obj->base, HSI2C_INT_SLAVE_ADDR_MATCH | HSI2C_INT_RX_ALMOST_FULL); + + hsi2c_set_fifo_level(obj->base); + hsi2c_set_auto_config(obj->base, 0, 0, 0); + + hsi2c_set_trans_mode(obj->base, 0, 0); + +#ifdef CONFIG_S5JS100_I2C_INTERRUPT_MODE + if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) { + irq_attach(priv->config->irq, priv->config->isr, NULL); + } +#endif +} + +static int hsi2c_setup(i2c_t *obj, unsigned int master, + unsigned int mode, unsigned int speed, unsigned int slave_addr) +{ + obj->master = master; + obj->mode = mode; + obj->xfer_speed = speed; + obj->slave_addr = slave_addr; + + hsi2c_manual_fast_init(obj); + + if (master == I2C_MASTER) { + hsi2c_master_setup(obj, mode, speed, slave_addr); + } else if (master == I2C_SLAVE_MODE) { + hsi2c_slave_setup(obj, mode, speed, slave_addr); + } + + return 0; +} + +unsigned int i2c_setclock(i2c_t *obj, unsigned int frequency) +{ + /* Has the I2C bus frequency changed? */ + if (frequency != obj->xfer_speed) { + /* + * Calculate the clock divider that results in the highest frequency + * that is than or equal to the desired speed. + */ + if (obj->mode != I2C_POLLING) { + hsi2c_conf(obj->base, frequency); + } + + hsi2c_calculate_timing(obj->base, obj->clock, frequency); + } + + /* Save the new I2C frequency */ + obj->xfer_speed = frequency; + return 0; +} + + + +static void clear_isr(i2c_t *obj) +{ + /* + * Writing to the IRQ status register clears set bits. Therefore, to + * clear indiscriminately, just read the register and write it back. + */ + uint32_t reg = obj->i2c->IRQ_STATUS; + obj->i2c->IRQ_STATUS = reg; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) +{ + /* Determine the I2C to use */ + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + + if ((int)obj->i2c == NC) { + error("I2C pin mapping failed"); + } + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); + + /* + * Default configuration: + * - MS : Master mode + * - NEA : Normal (7-bit) addressing + * - ACKEN : Send ACKs when reading from slave + * - CLR_FIFO : Not a configuration bit => clears the FIFO + */ + uint32_t reg = I2C_CTRL_MS | \ + I2C_CTRL_NEA | \ + I2C_CTRL_ACKEN | \ + I2C_CTRL_CLR_FIFO; + + obj->i2c->CONTROL = reg; + obj->base = I2C0_BASE; + obj->retries = 0; + obj->timeout = S5JS100_DEFAULT_I2C_TIMEOUT; + obj->master = I2C_MASTER; + obj->initialized = 0; + obj->clock = cal_clk_getrate(d1_acpu_l3); + obj->slave_addr = S5JS100_DEFAULT_I2CSLAVE_ADDR; + obj->mode = I2C_POLLING; + obj->addrlen = 7; + + hsi2c_setup(obj, obj->master, obj->mode, obj->xfer_speed, obj->slave_addr); + + i2c_setclock(obj, S5JS100_DEFAULT_I2CXFER_CLOCK); + //get_i2c_private(obj)->transfer_state = I2C_TRANSFER_SINGLE; + + //i2c_frequency(obj, 100000); /* Default to 100kHz SCL frequency */ +} + +int i2c_start(i2c_t *obj) +{ + return 0; +} + +int i2c_stop(i2c_t *obj) +{ + /* Clear the hardware FIFO */ + obj->i2c->CONTROL |= I2C_CTRL_CLR_FIFO; + /* Clear the HOLD bit used for performing combined transfers */ + obj->i2c->CONTROL &= ~I2C_CTRL_HOLD; + /* Reset the transfer size (read and write) */ + obj->i2c->TRANSFER_SIZE = 0; + /* Clear interrupts */ + clear_isr(obj); + return 0; +} + +void i2c_frequency(i2c_t *obj, int hz) +{ + /* + * Divider is split in two halfs : A and B + * A is 2 bits wide and B is 6 bits wide + * The Fscl frequency (SCL clock) is calculated with the following + * equation: + * Fscl=SystemCoreClock/(22*(A+1)*(B+1)) + * Here, we only calculate the B divisor which already enables a + * wide enough range of values + */ + unsigned int frequency = hz; + + if (frequency != obj->xfer_speed) { + if (obj->mode != I2C_POLLING) { + hsi2c_conf(obj->base, frequency); + } + hsi2c_calculate_timing(obj->base, obj->clock, frequency); + } +} + +int i2c_transfer(i2c_t *obj, struct i2c_msg_s *msgv, int msgc) +{ + struct i2c_msg_s *pmsg; + int ret = 0; + int i; + int nak_ok; + int start = 1; + int stop = 1; + //unsigned int base = obj->base; + + /* Ensure that address or flags don't change meanwhile */ + //s5js100_i2c_sem_wait(priv); + + /* TODO: initialization */ + if (start) { + hsi2c_start(obj); + } + + /* + if (obj->xfer_speed > I2C_SPEED_400KHZ) { + hsi2c_conf(base, I2C_SPEED_400KHZ); + putreg32((0xF << 24 | I2C_SEND_DATA), base + I2C_MANUAL_CMD); + hsi2c_wait_xfer_noack(priv); + + hsi2c_conf(base, priv->xfer_speed); + hsi2c_repstart(priv); + hsi2c_wait_xfer_noack(priv); + } + */ + + for (i = 0; i < msgc; i++) { + pmsg = &msgv[i]; + nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; + if (!(pmsg->flags & I2C_M_NOSTART)) { + if ((i > 0) || (start == 0)) { + hsi2c_repstart(obj); + hsi2c_wait_xfer_done(obj); + } + ret = do_address(obj, pmsg); + if ((ret != 0) && !nak_ok) { + goto fail; + } + } + if (pmsg->flags & I2C_M_READ) { + /* read bytes into buffer */ + ret = readbytes(obj, pmsg); + if (ret < pmsg->length) { + if (ret >= 0) { + return -EIO; + } + goto fail; + } + } else { + /* write bytes from buffer */ + ret = sendbytes(obj, pmsg); + if (ret < pmsg->length) { + if (ret >= 0) { + ret = -EIO; + } + goto fail; + } + } + } + +fail: + if (stop) { + hsi2c_stop(obj); + } + + /* Ensure that address or flags don't change meanwhile */ + //s5js100_i2c_sem_post(priv); + + return ret; +} +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) +{ + + struct i2c_msg_s xfer[2]; + + xfer[0].addr = (unsigned int)address; + xfer[0].flags = 0; + xfer[0].buffer = (unsigned char *)&data[0]; + xfer[0].length = 1; + + xfer[1].addr = (unsigned int)address; + xfer[1].flags = I2C_M_READ; + xfer[1].buffer = (unsigned char *)&data[1]; + xfer[1].length = length; + wait_us(100); + + return i2c_transfer(obj, xfer, 2); +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, + int stop) +{ + + struct i2c_msg_s msg; + + msg.addr = address; + msg.flags = (obj->addrlen == 10) ? I2C_M_TEN : 0; + msg.buffer = (unsigned char *)data; + msg.length = length; + + return i2c_transfer(obj, &msg, 1); +} + +void i2c_reset(i2c_t *obj) +{ + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) +{ + char i2c_ret = 0; + i2c_read(obj, obj->last_xfer_address, &i2c_ret, 1, last); + return i2c_ret; +} + +int i2c_byte_write(i2c_t *obj, int data) +{ + /* Store the number of written bytes */ + uint32_t wb = i2c_write(obj, obj->last_xfer_address, (char *)&data, 1, 0); + if (wb == 1) { + return 1; + } else { + return 0; + } +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) +{ +} + +int i2c_slave_receive(i2c_t *obj) +{ + return 0; +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) +{ + return 0; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) +{ + return 0; +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) +{ +} + +#endif // DEVICE_I2C diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_def.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_def.h new file mode 100644 index 0000000000..6de2d4864e --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/i2c_def.h @@ -0,0 +1,175 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/* + * I2C interface Support + * ===================== + */ + +#ifndef MBED_I2C_DEF_H +#define MBED_I2C_DEF_H + +#include /* standard types definitions */ + +typedef struct beetle_i2c { + __IO uint32_t CONTROL; /* RW Control register */ + __I uint32_t STATUS; /* RO Status register */ + __IO uint32_t ADDRESS; /* RW I2C address register */ + __IO uint32_t DATA; /* RW I2C data register */ + __IO uint32_t IRQ_STATUS; /* RO Interrupt status register ( read only but write to clear bits) */ + __IO uint32_t TRANSFER_SIZE; /* RW Transfer size register */ + __IO uint32_t SLAVE_MONITOR; /* RW Slave monitor pause register */ + __IO uint32_t TIMEOUT; /* RW Time out register */ + __I uint32_t IRQ_MASK; /* RO Interrupt mask register */ + __O uint32_t IRQ_ENABLE; /* WO Interrupt enable register */ + __O uint32_t IRQ_DISABLE; /* WO Interrupt disable register */ + +} I2C_TypeDef; + +// revise me +#define I2C0_BASE (0x83017000) /* Shield Header I2C Base Address */ +#define I2C1_BASE (0x4000E000ul) /* Onboard I2C Base Address */ + +#define SHIELD_I2C ((I2C_TypeDef *) I2C0_BASE ) +#define BOARD_I2C ((I2C_TypeDef *) I2C1_BASE ) + +/* Control Register Masks */ +#define I2C_CTRL_RW 0x0001 /* Transfer direction */ +#define I2C_CTRL_MS 0x0002 /* Mode (master / slave) */ +#define I2C_CTRL_NEA 0x0004 /* Addressing mode */ +#define I2C_CTRL_ACKEN 0x0008 /* ACK enable */ +#define I2C_CTRL_HOLD 0x0010 /* Clock hold enable */ +#define I2C_SLVMON 0x0020 /* Slave monitor mode */ +#define I2C_CTRL_CLR_FIFO 0x0040 /* Force clear of FIFO */ +#define I2C_CTRL_DIVISOR_B 0x3F00 /* Stage B clock divider */ +#define I2C_CTRL_DIVISOR_A 0xA000 /* Stage A clock divider */ +#define I2C_CTRL_DIVISORS 0xFF00 /* Combined A and B fields */ +#define I2C_CTRL_DIVISOR_OFFSET 8 /* Offset of the clock divisor in + * the CONTROL register + */ +#define I2C_CTRL_DIVISOR_A_BIT_MASK 0x03 +/* + * First part of the clock + * divisor in the CONTROL register + */ +#define I2C_CTRL_DIVISOR_B_BIT_MASK 0x3F +/* + * Second part of the clock + * divisor in the CONTROL register + */ + +/* Status Register Masks */ +#define I2C_STATUS_RXRW 0x0008 /* Mode of transmission from master */ +#define I2C_STATUS_RXDV 0x0020 /* Valid data waiting to be read */ +#define I2C_STATUS_TXDV 0x0040 /* Still a data byte to be sent */ +#define I2C_STATUS_RXOVF 0x0080 /* Receiver overflow */ +#define I2C_STATUS_BA 0x0100 /* Bus active */ + +/* Address Register Masks */ +#define I2C_ADDRESS_7BIT 0x007F + +/* Interrupt Status / Enable / Disable Register Masks */ +#define I2C_IRQ_COMP 0x0001 /* Transfer complete */ +#define I2C_IRQ_DATA 0x0002 /* More data */ +#define I2C_IRQ_NACK 0x0004 /* Transfer not acknowledged */ +#define I2C_IRQ_TO 0x0008 /* Transfer timed out */ +#define I2C_IRQ_SLV_RDY 0x0010 /* Monitored slave ready */ +#define I2C_IRQ_RX_OVF 0x0020 /* Receive overflow */ +#define I2C_IRQ_TX_OVF 0x0040 /* Transmit overflow */ +#define I2C_IRQ_RX_UNF 0x0080 /* Receive underflow */ +#define I2C_IRQ_ARB_LOST 0x0200 /* Arbitration lost */ + +/* Transfer Size Register Masks */ +#define I2C_TRANSFER_SIZE 0xFF + +/* Error codes */ +#define E_SUCCESS 0x0 +#define E_INCOMPLETE_DATA 0x1 + + +#define CTL 0x0000 +#define FIFO_CTL 0x0004 +#define TRAILING_CTL 0x0008 +#define INT_EN 0x0020 +#define INT_STAT 0x0024 +#define FIFO_STAT 0x0030 +#define TXDATA 0x0034 +#define RXDATA 0x0038 +#define I2C_CONF 0x0040 +#define I2C_AUTO_CONF 0x0044 +#define I2C_TIMEOUT 0x0048 +#define I2C_MANUAL_CMD 0x004C +#define I2C_TRANS_STATUS 0x0050 +#define I2C_TIMING_HS1 0x0054 +#define I2C_TIMING_HS2 0x0058 +#define I2C_TIMING_HS3 0x005C +#define I2C_TIMING_FS1 0x0060 +#define I2C_TIMING_FS2 0x0064 +#define I2C_TIMING_FS3 0x0068 +#define I2C_TIMING_SLA 0x006C +#define I2C_ADDR 0x0070 + +#define I2C_START (1 << 0) +#define I2C_RESTART (1 << 1) +#define I2C_STOP (1 << 2) +#define I2C_SEND_DATA (1 << 3) +#define I2C_READ_DATA (1 << 4) +#define I2C_RX_ACK (1 << 5) +#define I2C_TX_MASK (0xFF << 24) +#define I2C_RX_MASK (0xFF << 16) + +#define I2C_SPEED_400KHZ 400000 + +#define HSI2C_INT_SLAVE_ADDR_MATCH (1 << 15) +#define HSI2C_INT_XFER_DONE_MANUAL (1 << 13) +#define HSI2C_INT_XFER_DONE_NOACK_MANUAL (1 << 12) +#define HSI2C_INT_NO_DEV_AUTO (1 << 10) +#define HSI2C_INT_NO_DEV_ACK_AUTO (1 << 9) +#define HSI2C_INT_TRANS_ABORT_AUTO (1 << 8) +#define HSI2C_INT_TRANSFER_DONE_AUTO (1 << 7) +#define HSI2C_INT_RX_OVERRUN (1 << 5) +#define HSI2C_INT_TX_UNDERRUN (1 << 2) +#define HSI2C_INT_RX_ALMOST_FULL (1 << 1) +#define HSI2C_INT_TX_ALMOST_EMPTY (1 << 0) + +#define HSI2C_INT_ALL 0xFFFF + +#define I2C_M_READ 0x0001 /**< Read data, from slave to master */ +#define I2C_M_TEN 0x0002 /**< Ten bit address */ +#define I2C_M_NORESTART 0x0080 /**< Message should not begin with + * (re-)start of transfer */ +#define I2C_SLAVE 0x0703 /**< Use this slave address */ +#define I2C_SLAVE_FORCE 0x0706 /**< Use this slave address, even if it + * is already in use by a driver! */ +#define I2C_TENBIT 0x0704 /**< 0 for 7 bit addrs, != 0 for 10 bit */ +#define I2C_RDWR 0x0707 /**< Combined R/W transfer (one STOP only) */ + +#define I2C_FREQUENCY 0X801 + +#define I2C_M_IGNORE_NAK 0x1000 /**< if I2C_FUNC_PROTOCOL_MANGLING */ + +#define I2C_M_NOSTART 0x4000 /**< if I2C_FUNC_NOSTART */ + +#define I2C_MASTER 0 +#define I2C_SLAVE_MODE 1 +#define I2C_POLLING 0 +#define I2C_INTERRUPT 1 + + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_main_init.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_main_init.cpp new file mode 100644 index 0000000000..22980f1bd9 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_main_init.cpp @@ -0,0 +1,40 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "mbed.h" +#include "s5js100_pwr.h" +#include "modem_link_device_shmem.h" +#include "modem_io_device.h" + + +extern "C" { + + void s5js100_modem_start(void) + { + pShmemLinkDevice = new ShmemLinkDevice(); + pShmemLinkDevice->ShmemLinkDevice_start(); + } + + void s5js100_modem_stop(void) + { + delete pShmemLinkDevice; + } + +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_rtx.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_rtx.h new file mode 100644 index 0000000000..319bf7344c --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_rtx.h @@ -0,0 +1,28 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_MBED_RTX_H +#define MBED_MBED_RTX_H +#include + +#if defined(TARGET_SIDK_S5JS100) +#define INITIAL_SP 0x00180000 +#endif /* defined(TARGET_...) */ + +#endif /* MBED_MBED_RTX_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_sdk_init.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_sdk_init.c new file mode 100755 index 0000000000..e6a247f7e7 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/mbed_sdk_init.c @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "cmsis.h" +#include "s5js100_pmip.h" + +extern void s5js100_modem_start(void); +extern void sflash_os_env_parser(void); +void mbed_sdk_init(void) +{ + volatile unsigned int *wdtsfr = (unsigned int *)(0x83011000); + *wdtsfr = *wdtsfr & ~0x4; + + /* GPIO 0, 1 ouput for LED */ + modifyreg32(0x85026100, 0x3, 0x1); + modifyreg32(0x85026000, 0x3, 0x0); + + /* Beetle System Power Config */ + SystemPowerConfig(); + + s5js100_pmip_initialize(); + + /* Config EFlash Controller Clock */ + SFlash_DriverInitialize(); +// EFlash_ClockConfig(); + + sflash_os_env_parser(); +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/exynos_ipc.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/exynos_ipc.h new file mode 100644 index 0000000000..19111022aa --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/exynos_ipc.h @@ -0,0 +1,228 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __EXYNOS_IPC_H__ +#define __EXYNOS_IPC_H__ + +#define EXYNOS_SINGLE_MASK (0b11000000) +#define EXYNOS_MULTI_START_MASK (0b10000000) +#define EXYNOS_MULTI_LAST_MASK (0b01000000) + +#define EXYNOS_START_MASK 0xABCD +#define EXYNOS_START_OFFSET 0 +#define EXYNOS_START_SIZE 2 + +#define EXYNOS_FRAME_SEQ_OFFSET 2 +#define EXYNOS_FRAME_SIZE 2 + +#define EXYNOS_FRAG_CONFIG_OFFSET 4 +#define EXYNOS_FRAG_CONFIG_SIZE 2 + +#define EXYNOS_LEN_OFFSET 6 +#define EXYNOS_LEN_SIZE 2 + +#define EXYNOS_CH_ID_OFFSET 8 +#define EXYNOS_CH_SIZE 1 + +#define EXYNOS_CH_SEQ_OFFSET 9 +#define EXYNOS_CH_SEQ_SIZE 1 + +#define EXYNOS_HEADER_SIZE 12 + +#define EXYNOS_DATA_LOOPBACK_CHANNEL 82 + +#define EXYNOS_FMT_NUM 1 +#define EXYNOS_RFS_NUM 10 + +enum exynos_ch_id { + EXYNOS_CH_ID_MULTIPDP = 0, + + EXYNOS_CH_ID_PDP_0 = 1, /*rmnet0*/ + EXYNOS_CH_ID_PDP_1, + EXYNOS_CH_ID_PDP_2, + EXYNOS_CH_ID_PDP_3, + EXYNOS_CH_ID_PDP_4, + + EXYNOS_CH_ID_FMT_0 = 245, /*umts_ipc0*/ + EXYNOS_CH_ID_MAX = 255, + EXYNOS_CH_ID_FLOW_CTRL = 255 +}; + +struct __attribute__((packed)) frag_config { + unsigned char frame_first: 1, + frame_last: 1, + packet_index: 6; + unsigned char frame_index; +}; + +/* EXYNOS link-layer header */ +struct __attribute__((packed)) exynos_link_header { + unsigned short seq; + struct frag_config cfg; + unsigned short len; + unsigned short reserved_1; + unsigned char ch_id; + unsigned char ch_seq; + unsigned short reserved_2; +}; + +struct exynos_frame_data { + /* Frame length calculated from the length fields */ + unsigned int len; + + /* The length of link layer header */ + unsigned int hdr_len; + + /* The length of received header */ + unsigned int hdr_rcvd; + + /* The length of link layer payload */ + unsigned int pay_len; + + /* The length of received data */ + unsigned int pay_rcvd; + + /* The length of link layer padding */ + unsigned int pad_len; + + /* The length of received padding */ + unsigned int pad_rcvd; + + /* Header buffer */ + unsigned char hdr[EXYNOS_HEADER_SIZE]; +}; + +static inline bool exynos_start_valid(unsigned char *frm) +{ + unsigned short cfg = *(unsigned short *)(frm + EXYNOS_START_OFFSET); + return cfg == EXYNOS_START_MASK ? true : false; +} + +static inline bool exynos_multi_start_valid(unsigned char *frm) +{ + unsigned short cfg = *(unsigned short *)(frm + EXYNOS_FRAG_CONFIG_OFFSET); + return ((cfg >> 8) & EXYNOS_MULTI_START_MASK) == EXYNOS_MULTI_START_MASK; +} + +static inline bool exynos_multi_last_valid(unsigned char *frm) +{ + unsigned short cfg = *(unsigned short *)(frm + EXYNOS_FRAG_CONFIG_OFFSET); + return ((cfg >> 8) & EXYNOS_MULTI_LAST_MASK) == EXYNOS_MULTI_LAST_MASK; +} + +static inline bool exynos_single_frame(unsigned char *frm) +{ + unsigned short cfg = *(unsigned short *)(frm + EXYNOS_FRAG_CONFIG_OFFSET); + return ((cfg >> 8) & EXYNOS_SINGLE_MASK) == EXYNOS_SINGLE_MASK; +} + +static inline unsigned char exynos_get_ch(unsigned char *frm) +{ + return frm[EXYNOS_CH_ID_OFFSET]; +} + +static inline unsigned int exynos_get_frame_seq(unsigned char *frm) +{ + unsigned short cfg = *(unsigned short *)(frm + EXYNOS_FRAME_SEQ_OFFSET); + return cfg; +} + +static inline unsigned int exynos_get_ch_seq(unsigned char *frm) +{ + return frm[EXYNOS_CH_SEQ_OFFSET]; +} + +static inline unsigned int exynos_calc_padding_size(unsigned int len) +{ + unsigned int residue = len & 0x3; + return residue ? (4 - residue) : 0; +} + +static inline unsigned int exynos_get_frame_len(unsigned char *frm) +{ + return (unsigned int) * (unsigned short *)(frm + EXYNOS_LEN_OFFSET); +} + +static inline bool exynos_fmt_ch(unsigned char ch) +{ + return (ch == EXYNOS_CH_ID_FMT_0) ? true : false; +} + +static inline bool exynos_ps_ch(unsigned char ch) +{ + return (ch >= EXYNOS_CH_ID_PDP_0 && ch <= EXYNOS_CH_ID_PDP_4) ? + true : false; +} + +static inline unsigned int exynos_get_total_len(unsigned char *frm) +{ + unsigned int len; + unsigned int pad; + + len = exynos_get_frame_len(frm); + pad = exynos_calc_padding_size(len) ? exynos_calc_padding_size(len) : 0; + return len + pad; +} + +static inline bool exynos_padding_exist(unsigned char *frm) +{ + return exynos_calc_padding_size(exynos_get_frame_len(frm)) ? true : false; +} + +typedef struct { + int ch; + int len; + unsigned char *data; + unsigned char *header; + short pad; + short dalloc; +} mio_buf; + +inline mio_buf *alloc_mio_buf(int len) +{ + mio_buf *mio; + + mio = (mio_buf *)malloc(sizeof(mio_buf)); + if (mio == NULL) { + return NULL; + } + + if (len != 0) { + mio->data = (unsigned char *)malloc(len); + if (mio->data == NULL) { + free(mio); + return NULL; + } + mio->dalloc = 1; + } else { + mio->dalloc = 0; + } + + return mio; +} + +inline void free_mio_buf(mio_buf *mio) +{ + if (mio->dalloc != 0) { + free(mio->data); + } + free(mio); +} + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.cpp new file mode 100644 index 0000000000..fbc1c384b1 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +#include +#include "modem_io_device.h" +#include "modem_prj.h" +#include "modem_link_device_shmem.h" + +#include "mbed_trace.h" +#define TRACE_GROUP "IODEV" + +#ifndef MODEM_IO_DEVICE_DBG_ON +#define MODEM_IO_DEVICE_DBG_ON 0 +#endif +#define MODEM_IO_DEVICE_DBG if (MODEM_IO_DEVICE_DBG_ON) tr_info + +#define MODEM_IO_DEVICE_MAX sizeof(modem_io_deivce_list)/sizeof(ModemIoDevice *) + +ShmemIpcFmtDevice *ipc_fmt_dev = ShmemIpcFmtDevice::getInstance(); +ShmemIpcRawDevice *ipc_raw_dev = ShmemIpcRawDevice::getInstance(); + +IoDevMisc IoDev_ModemProxy((char *)"ModemProxy", 245, ipc_fmt_dev); +IoDevNet IoDev_rmnet1((char *)"rmnet1", 1, ipc_raw_dev); +IoDevMisc IoDev_shmem_save((char *)"shmem_save", 243, ipc_raw_dev); +IoDevMisc IoDev_dcxo((char *)"dcxo", 244, ipc_raw_dev); +IoDevMisc IoDev_if5((char *)"if5", 242, ipc_raw_dev); +IoDevNet IoDev_rmnet2((char *)"rmnet2", 2, ipc_raw_dev); +IoDevNet IoDev_rmnet3((char *)"rmnet3", 3, ipc_raw_dev); +IoDevNet IoDev_rmnet4((char *)"rmnet4", 4, ipc_raw_dev); +IoDevMisc IoDev_rmnet6((char *)"rmnet6", 6, ipc_raw_dev); +IoDevMisc IoDev_rmnet7((char *)"rmnet7", 7, ipc_raw_dev); +IoDevMisc IoDev_rmnet8((char *)"rmnet8", 8, ipc_raw_dev); +IoDevMisc IoDev_rmnet9((char *)"rmnet9", 9, ipc_raw_dev); + + +ModemIoDevice *modem_io_deivce_list[] = { + &IoDev_ModemProxy, + &IoDev_rmnet1, + &IoDev_shmem_save, + &IoDev_dcxo, + &IoDev_if5, + &IoDev_rmnet2, + &IoDev_rmnet3, + &IoDev_rmnet4, + &IoDev_rmnet6, + &IoDev_rmnet7, + &IoDev_rmnet8, + &IoDev_rmnet9, +}; + +ModemIoDevice *getModemIoDeviceByName(char *name) +{ + unsigned int i; + + for (i = 0; i < MODEM_IO_DEVICE_MAX; i++) { + if (modem_io_deivce_list[i] && !strncmp(modem_io_deivce_list[i]->name, name, 31)) { + return modem_io_deivce_list[i]; + } + } + return NULL; +} + +ModemIoDevice *getModemIoDeviceById(int ch) +{ + unsigned int i; + + for (i = 0; i < MODEM_IO_DEVICE_MAX; i++) { + if (modem_io_deivce_list[i] != NULL) { + if (modem_io_deivce_list[i]->id == ch) { + return modem_io_deivce_list[i]; + } + } + } + + return NULL; +} + +int ModemIoDevice::ioctl(int cmd, unsigned long arg) +{ + return 0; +} + +unsigned short ModemIoDevice::exynos_build_fr_config(unsigned int count) +{ + unsigned short fr_cfg = 0; + + if ((count + EXYNOS_HEADER_SIZE) <= 0xFFFF) { + fr_cfg |= (EXYNOS_SINGLE_MASK << 8); + } + + return fr_cfg; +} + +void ModemIoDevice::exynos_build_header(unsigned char *buff, unsigned short cfg, unsigned char ctl, int count) +{ + unsigned short *exynos_header = (unsigned short *)(buff + EXYNOS_START_OFFSET); + //unsigned short *frame_seq = (unsigned short *)(buff + EXYNOS_FRAME_SEQ_OFFSET); + unsigned short *frag_cfg = (unsigned short *)(buff + EXYNOS_FRAG_CONFIG_OFFSET); + unsigned short *size = (unsigned short *)(buff + EXYNOS_LEN_OFFSET); + + *exynos_header = EXYNOS_START_MASK; + //*frame_seq = ++(seq_num.frame_cnt); + *frag_cfg = cfg; + *size = (unsigned short)(EXYNOS_HEADER_SIZE + count); + buff[EXYNOS_CH_ID_OFFSET] = id; + + if (cfg == EXYNOS_SINGLE_MASK) { + *frag_cfg = cfg; + } + + buff[EXYNOS_CH_SEQ_OFFSET] = ++ch_cnt; +} + +int ModemIoDevice::write(const char *buf, int count) +{ + mio_buf *mio; + unsigned short fr_cfg; + size_t tailroom; + unsigned char header[EXYNOS_HEADER_SIZE]; + + MODEM_IO_DEVICE_DBG("%s:%d count(%d)\n", __func__, __LINE__, count); + + fr_cfg = exynos_build_fr_config(count); + tailroom = exynos_calc_padding_size(EXYNOS_HEADER_SIZE + count); + + mio = (mio_buf *)alloc_mio_buf(0); + if (!mio) { + return 0; + } + + exynos_build_header(header, fr_cfg, 0, count); + mio->header = header; + mio->data = (unsigned char *)buf; + mio->len = count; + mio->ch = id; + mio->pad = tailroom; + + ipc->send(mio); + return count; + +} + +void IoDevMisc::IoReadCallback(mio_buf *buf) +{ + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + if (read_cb != NULL) { + MODEM_IO_DEVICE_DBG("%s:%d name: %s\n", __func__, __LINE__, name); + read_cb(buf, cb_data); + return; + } + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + + if (rxq.full()) { + free_mio_buf(buf); + return; + } + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + + rxq.put(buf); +} + +int IoDevMisc::read(char *buf, int count) +{ + int copied = 0; + int tmp = 0; + osEvent evt; + mio_buf *mio; + int diff; + + if (remain.len) { + tmp = remain.len > count ? count : remain.len; + memcpy(buf, remain.data, tmp); + remain.len -= tmp; + if (remain.len == 0) { + free(remain.data); + } + count -= tmp; + if (!count) { + return tmp; + } + } + + if (rxq.empty()) { + return tmp; + } + + evt = rxq.get(osWaitForever); + + if (evt.status != (osStatus)osEventMessage) { + return tmp; + } + + mio = (mio_buf *)(evt.value.p); + copied += mio->len > count ? count : mio->len; + memcpy(buf, mio->data, copied); + + diff = mio->len - copied; + if (diff > 0) { + remain.data = (unsigned char *)malloc(diff); + if (remain.data) { + memcpy(remain.data, mio->data + copied, diff); + remain.len = diff; + } + } + + free(mio->data); + free(mio); + + return copied + tmp; +} + +int IoDevMisc::poll(int setup) +{ + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + r_sem->try_acquire_for(osWaitForever); + + return 0; +} + +void IoDevNet::IoReadCallback(mio_buf *buf) +{ + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + if (read_cb != NULL) { + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + read_cb(buf, cb_data); + free_mio_buf(buf); + return; + } + MODEM_IO_DEVICE_DBG("%s:%d\n", __func__, __LINE__); + free_mio_buf(buf); +} + +int IoDevNet::read(char *buf, int count) +{ + return 0; +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.h new file mode 100644 index 0000000000..b815eac4fb --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_io_device.h @@ -0,0 +1,169 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __MODEM_IO_DEVICE_H__ +#define __MODEM_IO_DEVICE_H__ + + +#include "pbuf.h" +#include "exynos_ipc.h" +#include "modem_link_device_shmem.h" + +typedef enum { + LINK_MODE_OFFLINE, + LINK_MODE_RELEASED, + LINK_MODE_IPC, +} link_mode; + + +class ModemIoDevice { +public: + char name[32]; + int id; + ShmemIpcDevice *ipc; + link_mode mode; + unsigned char ch_cnt; + void (*read_cb)(mio_buf *, void *); + void *cb_data; + +public: + virtual void IoReadCallback(mio_buf *) { } + virtual void open(void) { } + virtual void close(void) { } + virtual int read(char *buffer, int buflen) + { + return 0; + } + int write(const char *buffer, int buflen); + virtual int poll(int setup) + { + return 0; + } + int ioctl(int cmd, unsigned long arg); + void register_ReadCb(void (*cb)(mio_buf *, void *), void *data) + { + read_cb = cb; + cb_data = data; + } + + unsigned short exynos_build_fr_config(unsigned int count); + void exynos_build_header(unsigned char *buff, unsigned short cfg, unsigned char ctl, int count); +}; + +class IoDevMisc : public ModemIoDevice { +public: + Queue rxq; + mio_buf remain; + Semaphore *r_sem; + +public: + IoDevMisc(char *io_name, int ch, ShmemIpcDevice *ipc_dev) + { + strncpy(name, io_name, 31); + id = ch; + ipc = ipc_dev; + mode = LINK_MODE_OFFLINE; + ch_cnt = 0; + read_cb = NULL; + } + void IoReadCallback(mio_buf *); + void open(void) { } + void close(void) { } + int read(char *buffer, int buflen); + int poll(int setup); +}; + +class IoDevNet : public ModemIoDevice { +public: + IoDevNet(char *io_name, int ch, ShmemIpcDevice *ipc_dev) + { + strncpy(name, io_name, 31); + id = ch; + ipc = ipc_dev; + mode = LINK_MODE_OFFLINE; + ch_cnt = 0; + read_cb = NULL; + } + void IoReadCallback(mio_buf *); + void open(void) { } + void close(void) { } + int read(char *buffer, int buflen); + int poll(int setup) + { + return 0; + } +}; + + +#define IOC_VOID 0x20000000UL /* no parameters */ +#define _IO(x, y) (IOC_VOID|((x)<<8)|(y)) + +#define IOCTL_MODEM_ON _IO('o', 0x19) +#define IOCTL_MODEM_OFF _IO('o', 0x20) +#define IOCTL_MODEM_RESET _IO('o', 0x21) +#define IOCTL_MODEM_BOOT_ON _IO('o', 0x22) +#define IOCTL_MODEM_BOOT_OFF _IO('o', 0x23) +#define IOCTL_MODEM_BOOT_DONE _IO('o', 0x24) +#define IOCTL_MODEM_SAVE_RELEASE _IO('o', 0x38) +#define IOCTL_MODEM_START_SAVE _IO('o', 0x39) + +#define IOCTL_MODEM_PROTOCOL_SUSPEND _IO('o', 0x25) +#define IOCTL_MODEM_PROTOCOL_RESUME _IO('o', 0x26) + +#define IOCTL_MODEM_STATUS _IO('o', 0x27) +#define IOCTL_MODEM_DL_START _IO('o', 0x28) +#define IOCTL_MODEM_FW_UPDATE _IO('o', 0x29) + +#define IOCTL_MODEM_NET_SUSPEND _IO('o', 0x30) +#define IOCTL_MODEM_NET_RESUME _IO('o', 0x31) + +#define IOCTL_MODEM_DUMP_START _IO('o', 0x32) +#define IOCTL_MODEM_DUMP_UPDATE _IO('o', 0x33) +#define IOCTL_MODEM_FORCE_CRASH_EXIT _IO('o', 0x34) +#define IOCTL_MODEM_CP_UPLOAD _IO('o', 0x35) +#define IOCTL_MODEM_DUMP_RESET _IO('o', 0x36) + +#define IOCTL_MODEM_SWITCH_MODEM _IO('o', 0x37) + +#define IOCTL_MODEM_RAMDUMP_START _IO('o', 0xCE) +#define IOCTL_MODEM_RAMDUMP_STOP _IO('o', 0xCF) + +#define IOCTL_MODEM_XMIT_BOOT _IO('o', 0x40) +#define IOCTL_MODEM_GET_SHMEM_INFO _IO('o', 0x41) + +/* ioctl command for IPC Logger */ +#define IOCTL_MIF_LOG_DUMP _IO('o', 0x51) + +#define IOCTL_SHMEM_FULL_DUMP _IO('o', 0x54) /* For shmem dump */ +#define IOCTL_VSS_FULL_DUMP _IO('o', 0x57) /* For vss dump */ +#define IOCTL_ACPM_FULL_DUMP _IO('o', 0x58) /* For acpm memory dump */ + +/* ioctcl command for fast CP Boot */ +#define IOCTL_SEC_CP_INIT _IO('o', 0x61) +#define IOCTL_CHECK_SECURITY _IO('o', 0x62) +#define IOCTL_XMIT_BIN _IO('o', 0x63) + + +extern void registerModemIoDevice(ModemIoDevice *io); +extern ModemIoDevice *getModemIoDeviceByName(char *devname); +extern ModemIoDevice *getModemIoDeviceById(int ch); + + +#endif + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.cpp new file mode 100644 index 0000000000..dd5c1e97fb --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.cpp @@ -0,0 +1,809 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "modem_link_device_shmem.h" +#include "modem_io_device.h" +#include "modem_util.h" +#include "modem_prj.h" +#include "s5js100_error.h" +#include "s5js100_type.h" +#include + +#ifndef IPCRAM_PADDR +#define IPCRAM_PADDR 0x10000000 +#endif +#ifndef IPC_REGION_SIZE +#define IPC_REGION_SIZE SZ_64K +#endif +#if IPC_REGION_SIZE != SZ_64K +#error "Check IPC_REGION_SIZE! Refer to struct shmem_64KB_phys_map" +#endif + +#include "mbed_trace.h" +#define TRACE_GROUP "SMEM" + +#ifndef MODEM_LINK_DEVICE_SHMEM_DBG_ON +#define MODEM_LINK_DEVICE_SHMEM_DBG_ON 0 +#endif +#define MODEM_LINK_DEVICE_SHMEM_DBG if (MODEM_LINK_DEVICE_SHMEM_DBG_ON) tr_info + +#define SHMEM_CIRC_BUFFER_ERROR (-10) + + + + +static void shmem_irq_handler(void *data); +static void shmem_save_irq_handler(void *data); +static void shmem_stop_req_irq_handler(void *data); +int modem_link_device_thread_start(void); + +ShmemLinkDevice *pShmemLinkDevice; + +EventQueue *modem_link_device_wqueue; +Thread *msgrxwork; +Thread *irqwork; +Semaphore modem_link_device_sem(0, 512); + +bool shmem_ready = 0; + +int ShmemIpcDevice::get_txq_space(void) +{ + unsigned int head = *txq.head; + unsigned int tail = *txq.tail; + int space; + + if ((head >= txq.size) || (tail >= txq.size)) { + return SHMEM_CIRC_BUFFER_ERROR; + } + + space = tail - head - 1; + if (space < 0) { + space += txq.size; + } + + return space; +} + +void ShmemIpcDevice::write_ipc_to_txq(mio_buf *mio) +{ + unsigned int qsize = txq.size; + unsigned int in = *txq.head; + unsigned int *buff = (unsigned int *)txq.buff; + unsigned int *header = (unsigned int *)(mio->header); + unsigned int *src = (unsigned int *)(mio->data); + unsigned int len = mio->len; + unsigned int pad = mio->pad; + unsigned int i, j; + unsigned short *frame_seq = (unsigned short *)((char *)header + EXYNOS_FRAME_SEQ_OFFSET); + + *frame_seq = ++header_cnt; + + /* Write HEADER to the TXQ, assume that with padding aligned on 4 bytes */ + i = in >> 2; + for (j = 0; j < EXYNOS_HEADER_SIZE / 4; j++) { + buff[i] = header[j]; + i ++; + if (i == qsize >> 2) { + i = 0; + } + MBED_ASSERT(i < qsize >> 2); + } + + in += EXYNOS_HEADER_SIZE; + if (in >= qsize) { + in -= qsize; + } + + /* Write data to the TXQ, assume that with padding aligned on 4 bytes */ + i = in >> 2; + for (j = 0; j < (len + pad) / 4; j ++) { + buff[i] = src[j]; + i ++; + if (i == qsize >> 2) { + i = 0; + } + MBED_ASSERT(i < qsize >> 2); + } + + in += len + pad; + if (in >= qsize) { + in -= qsize; + } + + *txq.head = in; +} + +int ShmemIpcDevice::xmit_ipc_msg(mio_buf *msg) +{ +// shmem_circ_status circ; + int space; + int copied = 0; + bool chk_nospc = false; +#if MODEM_LINK_DEVICE_SHMEM_DBG_ON + int i; + char mm[96] = ""; +#endif + + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d", __func__, __LINE__); +#if MODEM_LINK_DEVICE_SHMEM_DBG_ON + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d ch[%d] len[%d]", __func__, __LINE__, msg->ch, msg->len); + for (i = 0; i < msg->len; i++) { + sprintf(mm + (i % 16) * 3, "%02X ", msg->data[i]); + //MODEM_LINK_DEVICE_SHMEM_DBG("%02X ", msg->data[i]); + if (i % 16 == 15 && i != 0) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s", mm); + } + } + if ((i - 1) % 16 != 15) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s", mm); + } +#endif + + + /* Acquire the spin lock for a TXQ */ + tx_lock->lock(); + + /* Get the size of free space in the TXQ */ + space = get_txq_space(); + if (space < 0) { + /* TXQ ERROR */ + copied = -EIO; + return copied;//break; + } + + /* TO DO - check free memory space if it fits all headres !!! + Check the free space size, + - FMT : comparing with mxb->len + - RAW : check used buffer size */ + chk_nospc = (space < msg->len) ? true : false; + + if (chk_nospc) { + /* TO DO - implement this back pressure to operate properly. */ + printf("ERROR Not implement %s:%d\n", __func__, __LINE__); + while (1); + /* Set res_required flag for the "dev" */ + res_required = 1; + + /* Take the mxb back to the mxb_txq */ + //mbuf_queue_head(txq, mxb); + + copied = -ENOSPC; + return copied;//break; + } + + /* TX only when there is enough space in the TXQ */ + write_ipc_to_txq(msg); + copied += msg->len; + free_mio_buf(msg); + + /* Release the spin lock */ + tx_lock->unlock(); + + return copied; +} + +int ShmemIpcDevice::send(mio_buf *buf) +{ + int ret; + + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d", __func__, __LINE__); + ret = xmit_ipc_msg(buf); + if (ret > 0) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d", __func__, __LINE__); + pShmemLinkDevice->send_int2cp(INT_NON_CMD(mask_send)); + } + + return 0; +} + +void ShmemIpcDevice::send_cmd(unsigned short cmd) +{ + ShmemLinkDevice *sld = pShmemLinkDevice; + + sld->send_int2cp(cmd); +} + +void ShmemIpcDevice::save_release(void) +{ + ShmemLinkDevice *sld = pShmemLinkDevice; + + sld->save_sem_release(); +} + +int ShmemIpcDevice::ioctl(unsigned int cmd, unsigned long arg) +{ + return 0; +} + +int ShmemIpcDevice::check_security(unsigned long arg) +{ + return 0; +} + +int ShmemIpcDevice::sec_init(unsigned long arg) +{ + return 0; +} + + +unsigned short ShmemLinkDevice::get_mbx_cp2ap_msg(void) +{ + return mbox_get_value(mbox.mbx_cp2ap_msg); +} + +unsigned short ShmemLinkDevice::get_mbx_ap2cp_msg(void) +{ + return mbox_get_value(mbox.mbx_ap2cp_msg); +} + +unsigned int ShmemLinkDevice::get_mbx_magic(void) +{ + unsigned int ret = getreg32(shmem_magic); + return ret; +} + +unsigned int ShmemLinkDevice::get_mbx_access(void) +{ + unsigned int ret = getreg32(shmem_access); + return ret; +} + +void ShmemLinkDevice::send_int2cp(unsigned short mask) +{ + mbox_set_value(mbox.mbx_ap2cp_msg, mask); + mbox_set_interrupt(mbox.int_ap2cp_msg); +} + +void ShmemLinkDevice::save_sem_release() +{ + save_sem->release(); +} + +int ShmemLinkDevice::init(void) +{ + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + + if (get_mbx_magic() == SHM_IPC_MAGIC && get_mbx_access() == 1 && state == STATE_ONLINE) { + return 0; // Already initialized + } + + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + + putreg32(0, shmem_access); + putreg32(SHM_IPC_MAGIC, shmem_magic); + putreg32(1, shmem_access); + state = STATE_ONLINE; + + return 0; +} + + +ShmemLinkDevice::ShmemLinkDevice() +{ + ipc_device[IPC_FMT] = ShmemIpcFmtDevice::getInstance(); + ipc_device[IPC_RAW] = ShmemIpcRawDevice::getInstance(); + + shmem_size = IPC_REGION_SIZE; + shmem_base = (void *)IPCRAM_PADDR; + shmem_magic = (unsigned int *) & (((struct shmem_64KB_phys_map *)IPCRAM_PADDR)->magic); + shmem_access = (unsigned int *) & (((struct shmem_64KB_phys_map *)IPCRAM_PADDR)->access); + memset(shmem_base, 0, shmem_size); + + /* Initialize locks, completions, and bottom halves */ + save_sem = new Semaphore(0, 1); + stop_sem = new Semaphore(0, 1); + ipc_rx_sem = new Semaphore(0, 512); + + mbox_ipc_register_handler(mbox.irq_cp2ap_msg, shmem_irq_handler, NULL); + mbox_ipc_register_handler(mbox.save_irq, shmem_save_irq_handler, NULL); + mbox_ipc_register_handler(mbox.stop_irq, shmem_stop_req_irq_handler, NULL); +} + +ShmemLinkDevice::~ShmemLinkDevice() +{ + printf("need to add code here ,%s\n\r", __func__); +} + +/* To avoid race conditions start of RX/TX threads should be done +* only after constructor is finished and ponter on new object is returned +*/ + +int ShmemLinkDevice::ShmemLinkDevice_start(void) +{ + return modem_link_device_thread_start(); +} + + +int ShmemLinkDevice::init_shmem_save(void) +{ + int i; + + if (get_mbx_magic() == SHM_SAVE_MAGIC && get_mbx_access() == 1) { + return 0; + } + + putreg32(0, shmem_access); + + for (i = 0; i < MAX_IPC_DEV; i++) { + putreg32(0, ipc_device[i]->txq.head); + putreg32(0, ipc_device[i]->txq.tail); + putreg32(0, ipc_device[i]->rxq.head); + putreg32(0, ipc_device[i]->rxq.tail); + ipc_device[i]->res_required = 0; + } + + putreg32(SHM_SAVE_MAGIC, shmem_magic); + putreg32(1, shmem_access); + + if (get_mbx_magic() != SHM_SAVE_MAGIC || get_mbx_access() != 1) { + return -13; + } + + state = STATE_NV_CS_SAVE; + + return 0; +} + +/** + * cmd_phone_start_handler + * + * Handles the PHONE_START command from a CP. + */ + +void rx_cmd_phone_start(void) +{ + ShmemLinkDevice *ld = pShmemLinkDevice; + int i; + + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + ld->init(); + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + + for (i = 0; i < MAX_IPC_DEV; i++) { + ld->ipc_device[i]->init(); + } + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + + ld->send_int2cp(INT_CMD(INT_CMD_INIT_END)); + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); +} + +void rx_cmd_cp_crash(void) +{ + printf("\n!!!!!CP Crash!!!!!\n"); + if (!strcmp(get_env("CRASHDUMP"), "ON")) { + mcpu_reset(); + mcpu_init(MCPU_CP); + } else { + MBED_ASSERT(0); + } +} + +static void cmd_handler(unsigned short cmd) +{ + switch (INT_CMD_MASK(cmd)) { + + case INT_CMD_PHONE_START: + rx_cmd_phone_start(); + break; + case INT_CMD_CRASH_EXIT: + rx_cmd_cp_crash(); + break; + default: + //mifdbg("SHMEM: unknown command 0x%04X\n", cmd); + break; + } +} +void ShmemIpcDevice::init(void) +{ + putreg32(0, txq.head); + putreg32(0, txq.tail); + putreg32(0, rxq.head); + putreg32(0, rxq.tail); + + res_required = 0; +} + + +void ShmemIpcDevice::done_req_ack(void) +{ + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + + if (req_ack_rcvd < 0) { + req_ack_rcvd = 0; + } + + if (req_ack_rcvd == 0) { + return; + } + + pShmemLinkDevice->send_int2cp(INT_NON_CMD(mask_res_ack)); + req_ack_rcvd--; + +} + +void ShmemIpcDevice::recv_res_ack(unsigned short intr) +{ + /* + This method is used to nodify about receiving response + from CP on req_ack sent earlier to confirm CPis alive + In fact we never sent is, so nothing to receive. + */ + if (intr & mask_res_ack) { + /* We should not get here!!! */ + while (1); + } +} + +void ShmemIpcDevice::recv_req_ack(unsigned short intr) +{ + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d\n", __func__, __LINE__); + + if (intr & mask_req_ack) { + req_ack_rcvd++; + } +} + + +ShmemIpcFmtDevice::ShmemIpcFmtDevice() +{ + struct shmem_64KB_phys_map *map; + + map = (struct shmem_64KB_phys_map *)IPCRAM_PADDR; + + strncpy(name, "FMT", 15); + + txq.head = (unsigned int *)(&(map->fmt_tx_head)); + txq.tail = (unsigned int *)(&(map->fmt_tx_tail)); + txq.buff = (unsigned char *)(map->fmt_tx_buff); + txq.size = SHM_64K_FMT_TX_BUFF_SZ; + + rxq.head = (unsigned int *)(&(map->fmt_rx_head)); + rxq.tail = (unsigned int *)(&(map->fmt_rx_tail)); + rxq.buff = (unsigned char *)(map->fmt_rx_buff); + rxq.size = SHM_64K_FMT_RX_BUFF_SZ; + + mask_req_ack = INT_MASK_REQ_ACK_F; + mask_res_ack = INT_MASK_RES_ACK_F; + mask_send = INT_MASK_SEND_F; + + res_required = 0; + + tx_lock = new Mutex("IPC_FMT"); + req_ack_cmpl = new Semaphore(1, 1); + + header_cnt = 0; +} + +ShmemIpcFmtDevice *ShmemIpcFmtDevice::getInstance(void) +{ + static ShmemIpcFmtDevice *s_ipcfmtdevice; + + if (s_ipcfmtdevice == NULL) { + s_ipcfmtdevice = new ShmemIpcFmtDevice(); + } + + return s_ipcfmtdevice; +} + +int ShmemIpcDevice::rx_ipc_frames(void) +{ + int i; + + /* buffer indeces are corrupted*/ + if ((*rxq.head >= rxq.size) || (*rxq.tail >= rxq.size)) { + return -5; + } + /* nothing to read */ + if (*rxq.head == *rxq.tail) { + return 0; + } + + ShmemLinkDevice *ld = pShmemLinkDevice; + + /** + * variables for the status of the circular queue + */ + unsigned char hdr[EXYNOS_HEADER_SIZE]; + /** + * variables for RX processing + */ + int rcvd; /* size of data in the RXQ or error */ + int rest; /* size of the rest data */ + unsigned int out; /* index to the start of current frame */ + int tot; /* total length including padding data */ + + rcvd = *rxq.head - *rxq.tail; + if (rcvd < 0) { + rcvd += rxq.size; + } + + rest = rcvd; + out = *rxq.tail; + + while (rest > 0) { + mio_buf *msg; + + if (rest < EXYNOS_HEADER_SIZE) { + return -75; + } + + for (i = 0; i < EXYNOS_HEADER_SIZE / 4; i ++) { + ((unsigned int *)hdr)[i] = ((unsigned int *)rxq.buff)[out >> 2]; + out += 4; + if (out >= rxq.size) { + out = 0; + } + } + + /* Check the config field in the header */ + if (!exynos_start_valid(hdr)) { + goto bad_msg; + } + + /* Verify the total length of the frame (data + padding) */ + tot = exynos_get_total_len(hdr); + if (tot > rest) { + goto bad_msg; + } + + msg = alloc_mio_buf(tot - EXYNOS_HEADER_SIZE); + for (i = 0; i < (tot - EXYNOS_HEADER_SIZE) / 4; i ++) { + ((unsigned int *)(msg->data))[i] = ((unsigned int *)rxq.buff)[out >> 2]; + out += 4; + if (out >= rxq.size) { + out = 0; + } + } + + + msg->ch = exynos_get_ch(hdr); + + if (msg->ch == 254) { + msg->len = tot - EXYNOS_HEADER_SIZE; + } else { + /* Use actual frame len to pass real payload length to upper layer */ + msg->len = exynos_get_frame_len(hdr) - EXYNOS_HEADER_SIZE; + } + + ld->ipc_rxq.put(msg); + ld->ipc_rx_sem->release(); + + /* Calculate new out value */ + rest -= tot; + } + + /* Update tail (out) pointer to empty out the RXQ */ + *rxq.tail = out; + + return rcvd; + +bad_msg: +#ifdef CONFIG_DEBUG_MODEM_IF + //mifdbg("SHMEM: ERR! rcvd:%d tot:%d rest:%d\n", rcvd, tot, rest); +#endif + return -74; +} + +ShmemIpcRawDevice::ShmemIpcRawDevice() +{ + struct shmem_64KB_phys_map *map; + + map = (struct shmem_64KB_phys_map *)IPCRAM_PADDR; + + memmove(name, "RAW", strlen("RAW")); + + txq.head = (unsigned int *)(&(map->raw_tx_head)); + txq.tail = (unsigned int *)(&(map->raw_tx_tail)); + txq.buff = (unsigned char *)(map->raw_tx_buff); + txq.size = SHM_64K_RAW_TX_BUFF_SZ; + + rxq.head = (unsigned int *)(&(map->raw_rx_head)); + rxq.tail = (unsigned int *)(&(map->raw_rx_tail)); + rxq.buff = (unsigned char *)(map->raw_rx_buff); + rxq.size = SHM_64K_RAW_RX_BUFF_SZ; + + mask_req_ack = INT_MASK_REQ_ACK_R; + mask_res_ack = INT_MASK_RES_ACK_R; + mask_send = INT_MASK_SEND_R; + + res_required = 0; + + req_ack_cmpl = new Semaphore(1, 1); + tx_lock = new Mutex("IPC_RAW"); + + header_cnt = 0; +} + +ShmemIpcRawDevice *ShmemIpcRawDevice::getInstance(void) +{ + static ShmemIpcRawDevice *s_ipclawdevice; + + if (s_ipclawdevice == NULL) { + s_ipclawdevice = new ShmemIpcRawDevice(); + } + + return s_ipclawdevice; +} + + +void ipc_rx_task(void); +static void shmem_irq_handler(void *data) +{ + modem_link_device_wqueue->call(ipc_rx_task); +} + +void ipc_shmem_save_task(void) +{ + ShmemLinkDevice *ld = pShmemLinkDevice; + mio_buf *msg; + + msg = alloc_mio_buf(12); + if (msg == NULL) { + return; + } + + ld->init_shmem_save(); + + msg->ch = 243; + strcpy((char *)(msg->data), "shmem_start"); + + ld->ipc_rxq.put(msg); + ld->ipc_rx_sem->release(); +} + +static void shmem_save_irq_handler(void *data) +{ + modem_link_device_wqueue->call(ipc_shmem_save_task); +} + +static void shmem_stop_req_irq_handler(void *data) +{ + /* DO SOMETHING here */ +} + +void msg_handler(void) +{ + ShmemLinkDevice *ld = pShmemLinkDevice; + ShmemIpcDevice *ipc; + int i; + int ret; + unsigned int magic; + + //MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d head[] = {%d, %d}, tail[] = {%d, %d}\n", __func__, __LINE__, head[0], head[1], tail[0], tail[1]); + + /* Is IPC active ? */ + if (ld->get_mbx_access() != 1) { + system_halt(); + } + magic = ld->get_mbx_magic(); + if (magic != SHM_IPC_MAGIC && magic != SHM_SAVE_MAGIC) { + system_halt(); + } + + /* Skip RX processing if there is no data in the RXQ */ + /* Read data in the RXQ */ + /* Process REQ_ACK (At this point, the RXQ may be empty.) */ + for (i = 0; i < MAX_IPC_DEV; i++) { + ipc = ld->ipc_device[i]; + ret = ipc->rx_ipc_frames(); + + /* TODO review below case and handle it properly!!! */ + /* In case of error just return. Shall we do aything here? */ + if (ret < 0) + while (1); + + ipc->done_req_ack(); + } +} + +void ipc_rx_task(void) +{ + ShmemLinkDevice *ld = pShmemLinkDevice; + unsigned short int2ap; + int i; + + /* get_shmem_status */ + int2ap = ld->get_mbx_cp2ap_msg(); + + /* Process a SHMEM command */ + if (INT_CMD_VALID(int2ap)) { + cmd_handler(int2ap); + return; + } + + if (INT_VALID(int2ap)) { + /* Make CP happy with our fake responses we are alive ... */ + /* However CP never sends it ... only SEND_R and SEND_F */ + /* Check and receive RES_ACK from CP */ + /* Check and receive REQ_ACK from CP */ + for (i = 0; i < MAX_IPC_DEV; i++) { + ld->ipc_device[i]->recv_res_ack(int2ap); + ld->ipc_device[i]->recv_req_ack(int2ap); + } + + msg_handler(); + } +} + +void msg_rx_work(void) +{ + ShmemLinkDevice *ld; + ModemIoDevice *iodev; + mio_buf *msg; + osEvent evt; +#if MODEM_LINK_DEVICE_SHMEM_DBG_ON + int i; + char mm[96] = ""; +#endif + + while (1) { + ld = pShmemLinkDevice; + ld->ipc_rx_sem->try_acquire(); + + while (!(ld->ipc_rxq.empty())) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d", __func__, __LINE__); + evt = ld->ipc_rxq.get(osWaitForever); + + if (evt.status != (osStatus)osEventMessage) { + continue; + } + + msg = (mio_buf *)(evt.value.p); +#if MODEM_LINK_DEVICE_SHMEM_DBG_ON + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d ch[%d] len[%d]", __func__, __LINE__, msg->ch, msg->len); + for (i = 0; i < msg->len; i++) { + sprintf(mm + (i % 16) * 3, "%02X ", msg->data[i]); + //MODEM_LINK_DEVICE_SHMEM_DBG("%02X ", msg->data[i]); + if (i % 16 == 15 && i != 0) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s", mm); + } + } + if ((i - 1) % 16 != 15) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s", mm); + } + MODEM_LINK_DEVICE_SHMEM_DBG("\n"); +#endif + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d ch:%d", __func__, __LINE__, msg->ch); + iodev = getModemIoDeviceById(msg->ch); + if (iodev != NULL) { + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d [%s]", __func__, __LINE__, iodev->name); + iodev->IoReadCallback(msg); + } else { + free_mio_buf(msg); + } + MODEM_LINK_DEVICE_SHMEM_DBG("%s:%d", __func__, __LINE__); + } + } +} + +int modem_link_device_thread_start(void) +{ + MODEM_LINK_DEVICE_SHMEM_DBG("%s\n", __func__); + msgrxwork = new rtos::Thread(osPriorityNormal, 2048, NULL, "msgrxwork"); + msgrxwork->start(msg_rx_work); + + modem_link_device_wqueue = new EventQueue(); + irqwork = new rtos::Thread(osPriorityNormal, 2048, NULL, "ipc_rx_task"); + irqwork->start(callback(modem_link_device_wqueue, &events::EventQueue::dispatch_forever)); + + return 0; +} + + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.h new file mode 100644 index 0000000000..255a50e4c8 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_link_device_shmem.h @@ -0,0 +1,242 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __MODEM_LINK_DEVICE_SHMEM_H__ +#define __MODEM_LINK_DEVICE_SHMEM_H__ + +#include "mbed.h" +#include "exynos_ipc.h" +#include "s5js100_mbox_ipc.h" + +typedef enum { + STATE_OFFLINE = 0, + STATE_ONLINE, + STATE_NV_CS_SAVE, +} modem_state; + +enum dev_format { + IPC_FMT = 0, + IPC_RAW, + MAX_IPC_DEV, +}; + +enum modem_io { + IODEV_MISC = 0, + IODEV_NET, + IODEV_DUMMY, +}; + +typedef struct { + unsigned int *head; + unsigned int *tail; + unsigned char *buff; + unsigned int size; +} shmem_circ; + +typedef struct { + unsigned char *buff; + unsigned int qsize; /* the size of a circular buffer */ + unsigned int in; + unsigned int out; + unsigned int size; /* the size of free space or received data */ +} shmem_circ_status; + + +class ShmemIpcDevice { +public: + char name[16]; + + shmem_circ txq; + shmem_circ rxq; + + unsigned short mask_req_ack; + unsigned short mask_res_ack; + unsigned short mask_send; + + int req_ack_rcvd; + int res_required; + Mutex *tx_lock; + Semaphore *req_ack_cmpl; + unsigned short header_cnt; +public: + + void done_req_ack(void); + void recv_req_ack(unsigned short intr); + void recv_res_ack(unsigned short intr); + void init(void); + + int init_comm(void) + { + return 0; + } + int release_shmem_mb(void) + { + return 0; + } + int resume_shmem_mb(void) + { + return 0; + } + void terminate_comm(void) { } + + int get_txq_space(void); + void write_ipc_to_txq(mio_buf *mxb); + int xmit_ipc_msg(mio_buf *mxb); + int send(mio_buf *mxb); + void send_cmd(unsigned short cmd); + void save_release(); + int ioctl(unsigned int cmd, unsigned long arg); + int check_security(unsigned long arg); + int sec_init(unsigned long arg); + + int rx_ipc_frames(void); +}; + +class ShmemIpcFmtDevice : public ShmemIpcDevice { +public: + ShmemIpcFmtDevice(); + ~ShmemIpcFmtDevice(); +// void TxWork(unsigned long arg) { } + static ShmemIpcFmtDevice *getInstance(void); +// int rx_ipc_frames(shmem_circ_status *circ); +}; + +class ShmemIpcRawDevice : public ShmemIpcDevice { +public: + ShmemIpcRawDevice(); + ~ShmemIpcRawDevice(); +// void TxWork(unsigned long arg) { } + static ShmemIpcRawDevice *getInstance(void); +// int rx_ipc_frames(shmem_circ_status *circ); +}; + + +class ShmemLinkDevice : public ExynosMboxIpc { +private: + modem_state state; + +public: + ShmemIpcDevice *ipc_device[MAX_IPC_DEV]; + int shmem_size; + void *shmem_base; + + /* Pointers (aliases) to IPC device map */ + unsigned int *shmem_magic; + unsigned int *shmem_access; + + Semaphore *save_sem; + Semaphore *stop_sem; + + Semaphore *ipc_rx_sem; + Queue ipc_rxq; + +public: + ShmemLinkDevice(); + ~ShmemLinkDevice(); + int ShmemLinkDevice_start(void); + unsigned short get_mbx_cp2ap_msg(void); + unsigned short get_mbx_ap2cp_msg(void); + unsigned int get_mbx_magic(void); + unsigned int get_mbx_access(void); + void send_int2cp(unsigned short mask); + void save_sem_release(void); + int init(void); + modem_state getstate(void) + { + return state; + } + void setstate(modem_state st) + { + state = st; + } + + int IsCpOffline(void) + { + return (state == STATE_OFFLINE); + } + + int IsCpOnline(void) + { + return (state == STATE_ONLINE); + } + + int IsCpNvCsSave(void) + { + return (state == STATE_NV_CS_SAVE); + } + int init_shmem_save(void); +}; + +extern ShmemLinkDevice *pShmemLinkDevice; + +/* shmem message */ +#define INT_MASK_REQ_ACK_F 0x0020 +#define INT_MASK_REQ_ACK_R 0x0010 +#define INT_MASK_RES_ACK_F 0x0008 +#define INT_MASK_RES_ACK_R 0x0004 +#define INT_MASK_SEND_F 0x0002 +#define INT_MASK_SEND_R 0x0001 + +#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */ +#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */ +#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */ + +#define INT_MASK_REQ_ACK_SET \ + (INT_MASK_REQ_ACK_F | INT_MASK_REQ_ACK_R | INT_MASK_REQ_ACK_RFS) + +#define INT_MASK_RES_ACK_SET \ + (INT_MASK_RES_ACK_F | INT_MASK_RES_ACK_R | INT_MASK_RES_ACK_RFS) + + + +/* shmem physical memory */ +#define SHM_IPC_MAGIC 0x000000AA +#define SHM_SAVE_MAGIC 0x76617300 + +#define SHM_64K_RESERVED_SZ (8 + 16) +#define SHM_64K_FMT_TX_BUFF_SZ 0x3FE0 +#define SHM_64K_FMT_RX_BUFF_SZ 0x3FE0 +#define SHM_64K_RAW_TX_BUFF_SZ 0x4000 +#define SHM_64K_RAW_RX_BUFF_SZ 0x4000 + +struct shmem_64KB_phys_map { + unsigned int magic; + unsigned int access; + + unsigned int fmt_tx_head; + unsigned int fmt_tx_tail; + + unsigned int fmt_rx_head; + unsigned int fmt_rx_tail; + + unsigned int raw_tx_head; + unsigned int raw_tx_tail; + + unsigned int raw_rx_head; + unsigned int raw_rx_tail; + + unsigned char reserved[SHM_64K_RESERVED_SZ]; + + unsigned char fmt_tx_buff[SHM_64K_FMT_TX_BUFF_SZ]; + unsigned char fmt_rx_buff[SHM_64K_FMT_RX_BUFF_SZ]; + + unsigned char raw_tx_buff[SHM_64K_RAW_TX_BUFF_SZ]; + unsigned char raw_rx_buff[SHM_64K_RAW_RX_BUFF_SZ]; +} __attribute__((packed)); +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_prj.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_prj.h new file mode 100644 index 0000000000..5126c54fc6 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_prj.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __MODEM_PRJ_H__ +#define __MODEM_PRJ_H__ + +/* interrupt masks.*/ +#define INT_MASK_VALID 0x0080 +#define INT_MASK_CMD 0x0040 +#define INT_VALID(x) ((x) & INT_MASK_VALID) +#define INT_CMD_VALID(x) ((x) & INT_MASK_CMD) +#define INT_NON_CMD(x) (INT_MASK_VALID | (x)) +#define INT_CMD(x) (INT_MASK_VALID | INT_MASK_CMD | (x)) +#define INT_CMD_MASK(x) ((x) & 0x1F) + +typedef enum { + INT_CMD_INIT_START = 0x1, + INT_CMD_COLD_BOOT = 0x2, + INT_CMD_WARM_BOOT = 0x3, + INT_CMD_INIT_END = 0x2, + INT_CMD_REQ_ACTIVE = 0x3, + INT_CMD_RES_ACTIVE = 0x4, + INT_CMD_REQ_TIME_SYNC = 0x5, + INT_CMD_REQ_OFF = 0x6, + INT_CMD_CRASH_RESET = 0x7, + INT_CMD_PHONE_START = 0x8, + INT_CMD_ERR_DISPLAY = 0x9, + INT_CMD_CRASH_EXIT = 0x9, + INT_CMD_CP_DEEP_SLEEP = 0xA, + INT_CMD_NV_REBUILDING = 0xB, + INT_CMD_EMER_DOWN = 0xC, + INT_CMD_PIF_INIT_DONE = 0xD, + INT_CMD_SILENT_NV_REBUILDING = 0xE, + INT_CMD_NORMAL_POWER_OFF = 0xF, + INT_CMD_MODEM_RELEASE = 0x10, + INT_CMD_MAX = 0x11, +} MODEM_INT_CMD; + +enum direction { + TX = 0, + RX, + MAX_DIR +}; + + +#endif + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_util.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_util.h new file mode 100644 index 0000000000..d7edddeb93 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/modem_util.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __MODEM_UTIL_H__ +#define __MODEM_UTIL_H__ + +#define SZ_1 0x00000001 +#define SZ_2 0x00000002 +#define SZ_4 0x00000004 +#define SZ_8 0x00000008 +#define SZ_16 0x00000010 +#define SZ_32 0x00000020 +#define SZ_64 0x00000040 +#define SZ_128 0x00000080 +#define SZ_256 0x00000100 +#define SZ_512 0x00000200 + +#define SZ_1K 0x00000400 +#define SZ_2K 0x00000800 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_32K 0x00008000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.cpp new file mode 100644 index 0000000000..38fcd6e456 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.cpp @@ -0,0 +1,329 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "mbed.h" +#include "s5js100_mbox_ipc.h" +#include "s5js100_type.h" +#include "s5js100_error.h" +#include "shmem_save.h" + +#define S5JS100_MBOX_IPC_DBG_ON 0 +#define S5JS100_MBOX_IPC_DBG if (S5JS100_MBOX_IPC_DBG_ON) printf + +/***************************************************************/ +/* MCU_IPC Registers part */ +/***************************************************************/ +#define S5JS100_MAILBOX_BASE (0x85023000) +#define EXYNOS_MCU_IPC_MCUCTLR ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0000)) +#define EXYNOS_MCU_IPC_INTGR0 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0008)) +#define EXYNOS_MCU_IPC_INTCR0 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x000c)) +#define EXYNOS_MCU_IPC_INTMR0 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0010)) +#define EXYNOS_MCU_IPC_INTSR0 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0014)) +#define EXYNOS_MCU_IPC_INTMSR0 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0018)) +#define EXYNOS_MCU_IPC_INTGR1 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x001c)) +#define EXYNOS_MCU_IPC_INTCR1 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0020)) +#define EXYNOS_MCU_IPC_INTMR1 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0024)) +#define EXYNOS_MCU_IPC_INTSR1 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0028)) +#define EXYNOS_MCU_IPC_INTMSR1 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x002c)) +#define EXYNOS_MCU_IPC_ISSR0 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0080)) +#define EXYNOS_MCU_IPC_ISSR1 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0084)) +#define EXYNOS_MCU_IPC_ISSR2 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x0088)) +#define EXYNOS_MCU_IPC_ISSR3 ((volatile unsigned int *)(S5JS100_MAILBOX_BASE + 0x008c)) + +/***************************************************************/ +/* MCU_IPC Bit definition part */ +/***************************************************************/ +/* SYSREG Bit definition */ +#define MCU_IPC_MCUCTLR_MSWRST (0) /* MCUCTRL S/W Reset */ + +#define MCU_IPC_RX_INT0 (1 << 16) +#define MCU_IPC_RX_INT1 (1 << 17) +#define MCU_IPC_RX_INT2 (1 << 18) +#define MCU_IPC_RX_INT3 (1 << 19) +#define MCU_IPC_RX_INT4 (1 << 20) +#define MCU_IPC_RX_INT5 (1 << 21) +#define MCU_IPC_RX_INT6 (1 << 22) +#define MCU_IPC_RX_INT7 (1 << 23) +#define MCU_IPC_RX_INT8 (1 << 24) +#define MCU_IPC_RX_INT9 (1 << 25) +#define MCU_IPC_RX_INT10 (1 << 26) +#define MCU_IPC_RX_INT11 (1 << 27) +#define MCU_IPC_RX_INT12 (1 << 28) +#define MCU_IPC_RX_INT13 (1 << 29) +#define MCU_IPC_RX_INT14 (1 << 30) +#define MCU_IPC_RX_INT15 (1 << 31) + +#define MIF_INT_AP2CP_MSG 0 +#define MIF_INT_AP2CP_WAKEUP 1 +#define MIF_INT_AP2CP_STATUS 2 +#define MIF_INT_AP2CP_ACTIVE 3 +#define MIF_INT_AP2CP_DCXO 12 + +#define MIF_IRQ_CP2AP_MSG 0 +#define MIF_IRQ_CP2AP_WAKEUP 1 +#define MIF_IRQ_CP2AP_STATUS 2 +#define MIF_IRQ_CP2AP_LTE_ACTIVE 4 +#define MIF_IRQ_CP2AP_WAKELOCK 8 +#define MIF_IRQ_CP2AP_SAVE 11 +#define MIF_IRQ_CP2AP_DCXO 12 +#define MIF_IRQ_CP2AP_STOP_REQ 13 + +#define MIF_MBX_AP2CP_MSG 0 +#define MIF_MBX_CP2AP_MSG 1 +#define MIF_MBX_AP2CP_STATUS 2 +#define MIF_MBX_CP2AP_STATUS 3 +//#define MIF_MBX_DCXO_MSG 4 +#define MIF_MBX_BOOT_MSG 4 +#define MIF_MBX_CSADDR_MSG 5 +#define MIF_MBX_NVADDR_MSG 6 +#define MIF_MBX_CALADDR_MSG 7 + + +#define MAX_MBOX_NUM 64 +#define S5JS100_IRQ_MAILBOX_AP_INT ((IRQn_Type )31) + + +struct ipc_cp_hd { + void *data; + void (*handler)(void *); +} mbox_ipc_cp_hd[16]; + +static void mbox_ipc_cp_clear_all_interrupt(void) +{ + putreg32(0xFFFF, EXYNOS_MCU_IPC_INTCR1); +} + +static void mbox_ipc_cp_clear_all_boxes(void) +{ + unsigned long long i; + + for (i = 0; i < 8; i++) { + putreg32(0, EXYNOS_MCU_IPC_ISSR0 + i); + } +} + +static void mbox_ipc_cp_handler(int32_t irq, void *context, void *arg) +{ + unsigned int irq_stat, i; + + irq_stat = getreg32(EXYNOS_MCU_IPC_INTSR0) & 0xFFFF0000; + + /* Interrupt Clear */ + putreg32(irq_stat, EXYNOS_MCU_IPC_INTCR0); + S5JS100_MBOX_IPC_DBG("%s irq_stat=0x%08X\n", __func__, irq_stat); + irq_stat = irq_stat >> 16; + + for (i = 0; i < 16 && irq_stat; i++) { + if (irq_stat & (1 << i)) { + if (mbox_ipc_cp_hd[i].handler != NULL) { + mbox_ipc_cp_hd[i].handler(mbox_ipc_cp_hd[i].data); + } + irq_stat &= ~(1 << (i + 16)); + } + } + NVIC_ClearPendingIRQ(S5JS100_IRQ_MAILBOX_AP_INT); +} + +extern "C" { + extern char *get_env(const char *name); +} + +void ExynosMboxIpc::mbox_init(void) +{ + unsigned int cs, nv, cal; + char *epco; + + shmem_get_data(&cs, &nv, &cal); + + /* Request IRQ */ + NVIC_SetVector(S5JS100_IRQ_MAILBOX_AP_INT, (uint32_t)mbox_ipc_cp_handler); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + + mbox_ipc_cp_clear_all_interrupt(); + mbox_ipc_cp_clear_all_boxes(); + + if (get_bootflag()) { + mbox_set_value(MIF_MBX_BOOT_MSG, 0); + } else { + mbox_set_value(MIF_MBX_BOOT_MSG, 1); + } + + mbox_set_value(MIF_MBX_CSADDR_MSG, cs); + mbox_set_value(MIF_MBX_NVADDR_MSG, nv); + mbox_set_value(MIF_MBX_CALADDR_MSG, cal); + + epco = get_env("ePCO"); + if (epco != NULL && epco[0] == '0') { + modifyreg32(0x85023088, 0x00000800, 0x00000800); + } else { + modifyreg32(0x85023088, 0x00000800, 0x00000000); + } + + NVIC_EnableIRQ(S5JS100_IRQ_MAILBOX_AP_INT); + +} + +void ExynosMboxIpc::mbox_deinit(void) +{ + NVIC_DisableIRQ(S5JS100_IRQ_MAILBOX_AP_INT); +} + +void ExynosMboxIpc::mbox_sw_reset(void) +{ + unsigned int reg_val; + + reg_val = getreg32(EXYNOS_MCU_IPC_MCUCTLR); + reg_val |= (0x1 << MCU_IPC_MCUCTLR_MSWRST); + + putreg32(reg_val, EXYNOS_MCU_IPC_MCUCTLR) ; + + while (getreg32(EXYNOS_MCU_IPC_MCUCTLR) & (0x1 << MCU_IPC_MCUCTLR_MSWRST)); +} + +void ExynosMboxIpc::mbox_update_value(unsigned int mbx_num, unsigned int msg, unsigned int mask, unsigned int pos) +{ + unsigned int val; + + if (mbx_num < MAX_MBOX_NUM) { + val = mbox_get_value(mbx_num); + val &= ~(mask << pos); + val |= (msg & mask) << pos; + mbox_set_value(mbx_num, val); + } +} + +unsigned int ExynosMboxIpc::mbox_extract_value(unsigned int mbx_num, unsigned int mask, unsigned int pos) +{ + if (mbx_num < MAX_MBOX_NUM) { + return (mbox_get_value(mbx_num) >> pos) & mask; + } else { + return 0; + } +} + +void ExynosMboxIpc::mbox_set_value(unsigned int mbx_num, unsigned int msg) +{ + if (mbx_num < MAX_MBOX_NUM) { + putreg32(msg, EXYNOS_MCU_IPC_ISSR0 + mbx_num); + } +} + +unsigned int ExynosMboxIpc::mbox_get_value(unsigned int mbx_num) +{ + if (mbx_num < MAX_MBOX_NUM) { + return getreg32(EXYNOS_MCU_IPC_ISSR0 + mbx_num); + } else { + return 0; + } +} + +void ExynosMboxIpc::mbox_set_interrupt(unsigned int int_num) +{ + /* generate interrupt */ + if (int_num < 16) { + putreg32(0x1 << int_num, EXYNOS_MCU_IPC_INTGR1); + } +} + +void ExynosMboxIpc::mbox_ipc_send_command(unsigned int int_num, unsigned short cmd) +{ + /* write command */ + if (int_num < 16) { + putreg32(cmd, EXYNOS_MCU_IPC_ISSR0 + (2 * int_num)); + } + + /* generate interrupt */ + mbox_set_interrupt(int_num); +} + +int ExynosMboxIpc::mbox_ipc_unregister_handler(unsigned int int_num) +{ + mbox_ipc_cp_hd[int_num].data = NULL; + mbox_ipc_cp_hd[int_num].handler = NULL; + + return 0; +} + +int ExynosMboxIpc::mbox_ipc_register_handler(unsigned int int_num, void (*handler)(void *), void *data) +{ + if ((!handler) || (int_num > 15)) { + return_error(-EINVAL); + } + + mbox_ipc_cp_hd[int_num].data = data; + mbox_ipc_cp_hd[int_num].handler = handler; + + return 0; +} + +int ExynosMboxIpc::mbox_attach_isr() +{ + /* Request IRQ */ + NVIC_SetVector(S5JS100_IRQ_MAILBOX_AP_INT, (uint32_t)mbox_ipc_cp_handler); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + + mbox_ipc_cp_clear_all_interrupt(); + mbox_ipc_cp_clear_all_boxes(); + + NVIC_EnableIRQ(S5JS100_IRQ_MAILBOX_AP_INT); + + return 0; +} + +int ExynosMboxIpc::mbox_detach_isr() +{ + NVIC_DisableIRQ(S5JS100_IRQ_MAILBOX_AP_INT); + + return 0; +} + +ExynosMboxIpc::ExynosMboxIpc() +{ + mbox.int_ap2cp_msg = MIF_INT_AP2CP_MSG; + mbox.int_ap2cp_status = MIF_INT_AP2CP_STATUS; + mbox.int_ap2cp_active = MIF_INT_AP2CP_ACTIVE; + + mbox.irq_cp2ap_msg = MIF_IRQ_CP2AP_MSG; + mbox.irq_cp2ap_status = MIF_IRQ_CP2AP_STATUS; + mbox.irq_cp2ap_active = MIF_IRQ_CP2AP_LTE_ACTIVE; + + mbox.mbx_ap2cp_msg = MIF_MBX_AP2CP_MSG; + mbox.mbx_cp2ap_msg = MIF_MBX_CP2AP_MSG; + mbox.mbx_ap2cp_status = MIF_MBX_AP2CP_STATUS; + mbox.mbx_cp2ap_status = MIF_MBX_CP2AP_STATUS; + + mbox.irq_cp2ap_save = MIF_IRQ_CP2AP_SAVE; + mbox.irq_cp2ap_stop_req = MIF_IRQ_CP2AP_STOP_REQ; + + mbox.save_irq = MIF_IRQ_CP2AP_SAVE; + mbox.stop_irq = MIF_IRQ_CP2AP_STOP_REQ; +} + +ExynosMboxIpc::~ExynosMboxIpc() +{ +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.h new file mode 100644 index 0000000000..d08b9d8e59 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/s5js100_mbox_ipc.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __EXYNOS_MBOX_IPC_H__ +#define __EXYNOS_MBOX_IPC_H__ + +#ifndef NUM_OF_MBOX_IPC +#define NUM_OF_MBOX_IPC 1 +#endif +#if NUM_OF_MBOX_IPC == 0 +#error "wrong NUM_OF_MBOX_IPC" +#endif + +class ExynosMboxIpc { +public: + struct { + unsigned int mbx_ap2cp_msg; + unsigned int mbx_cp2ap_msg; + unsigned int mbx_ap2cp_status; + unsigned int mbx_cp2ap_status; + + int int_ap2cp_msg; + int int_ap2cp_active; + int int_ap2cp_status; + + int irq_cp2ap_msg; + int irq_cp2ap_active; + int irq_cp2ap_status; + + int irq_cp2ap_save; + int irq_cp2ap_stop_req; + + int save_irq; + int stop_irq; + } mbox; + +public: + void mbox_init(void); + void mbox_deinit(void); + void mbox_sw_reset(void); + void mbox_update_value(unsigned int mbx_num, unsigned int msg, unsigned int mask, unsigned int pos); + unsigned int mbox_extract_value(unsigned int mbx_num, unsigned int mask, unsigned int pos); + void mbox_set_value(unsigned int mbx_num, unsigned int msg); + unsigned int mbox_get_value(unsigned int mbx_num); + void mbox_ipc_send_command(unsigned int int_num, unsigned short cmd); + int mbox_ipc_unregister_handler(unsigned int int_num); + int mbox_ipc_register_handler(unsigned int int_num, void (*handler)(void *), void *data); + void mbox_set_interrupt(unsigned int int_num); + int mbox_attach_isr(); + int mbox_detach_isr(); + +public: + ExynosMboxIpc(); + ~ExynosMboxIpc(); +}; + +#endif + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.cpp new file mode 100644 index 0000000000..2c553f4a2b --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.cpp @@ -0,0 +1,363 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "mbed.h" +#include "shmem_save.h" +#include "modem_io_device.h" +#include "s5js100_pwr.h" +#include "sflash_api.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FLASH_CS_BASE_OLD 0x40EAA000 +#define FLASH_NV_BASE_OLD 0x40E47000 +#define FLASH_CAL_BASE_OLD 0x40E87000 + +#define FLASH_CS_BASE 0x4059B000 +#define FLASH_NV_BASE 0x4055B000 +#define FLASH_CAL_BASE 0x4001B000 + +#define FLASH_CS_SIZE (1024 * 300) +#define FLASH_NV_SIZE (1024 * 256) +#define FLASH_CAL_SIZE (1024 * 128) + +#define REQ_CS_MSG 0x0000A20B +#define REQ_NV_MSG 0x0000A21B +#define REQ_CAL_MSG 0x0000A22B + +#define BUFFER_SIZE 256 +#define SFLASH_SECTOR_SIZE 256 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +static ModemIoDevice *shmem_mio; +static unsigned int cur_save_target; +static unsigned char *save_cached; +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +extern int nbsleep_req; +unsigned int g_flash_cs_base; +unsigned int g_flash_nv_base; +unsigned int g_flash_cal_base; + +unsigned int g_flash_cs_size = FLASH_CS_SIZE; +unsigned int g_flash_nv_size = FLASH_NV_SIZE; +unsigned int g_flash_cal_size = FLASH_CAL_SIZE; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#define SHMEM_SECTION_MAGIC (0x06313184) +typedef struct { + unsigned int magic0; + unsigned int version; + unsigned int start; + unsigned int magic1; +} shmem_section_data; + +static shmem_section_data next_shmem_section[3] = { + {SHMEM_SECTION_MAGIC, 1, g_flash_cs_base + (48 * 1024), SHMEM_SECTION_MAGIC}, + {SHMEM_SECTION_MAGIC, 1, g_flash_nv_base + (48 * 1024), SHMEM_SECTION_MAGIC}, + {SHMEM_SECTION_MAGIC, 1, g_flash_cal_base + (48 * 1024), SHMEM_SECTION_MAGIC}, +}; + +static shmem_section_data *find_section_data(unsigned int start, unsigned int size) +{ + unsigned int a, max; + shmem_section_data *d, *m; + + max = 0; + m = NULL; + for (a = start; a < start + size; a += 0x1000) { + d = (shmem_section_data *)(a + 0x1000 - sizeof(shmem_section_data)); + if (d->magic0 != 0x06313184 || d->magic1 != 0x06313184) { + continue; + } + + if (d->version > max) { + max = d->version; + m = d; + } + } + + return m; +} + +extern uint32_t s5js100_sflash_read_capacity(void); + +void shmem_get_data(unsigned int *cs, unsigned int *nv, unsigned int *cal) +{ + struct { + unsigned int start; + unsigned int size; + } section[3]; + unsigned int i; + shmem_section_data *m; + unsigned int ret[3] = {0, 0, 0}; + //unsigned int FLASH16MB = 0, oldstart, oldsize; + //unsigned int psize, poffset; + //unsigned char *tmpbuf; + //shmem_section_data *tmpsection; + + //initialize SHMEM section depending on FLASH capacity + if (s5js100_sflash_read_capacity() == 16 * 1024 * 1024) { + g_flash_cs_base = FLASH_CS_BASE_OLD; + g_flash_nv_base = FLASH_NV_BASE_OLD; + g_flash_cal_base = FLASH_CAL_BASE_OLD; + } else if (s5js100_sflash_read_capacity() == 8 * 1024 * 1024) { + g_flash_cs_base = FLASH_CS_BASE; + g_flash_nv_base = FLASH_NV_BASE; + g_flash_cal_base = FLASH_CAL_BASE; + } else { + printf("no support FLASH size..\n"); + } + + section[0].start = g_flash_cs_base; + section[1].start = g_flash_nv_base; + section[2].start = g_flash_cal_base; + + section[0].size = g_flash_cs_size; + section[1].size = g_flash_nv_size; + section[2].size = g_flash_cal_size; + + for (i = 0; i < 3; i++) { + m = find_section_data(section[i].start, section[i].size); + + if (m == NULL) { + ret[i] = section[i].start; + next_shmem_section[i].start = section[i].start + (48 * 1024); + } else { + ret[i] = m->start; + next_shmem_section[i].start = (unsigned int)m + sizeof(shmem_section_data); + next_shmem_section[i].version = m->version + 1; + } + } + + *cs = ret[0]; + *nv = ret[1]; + *cal = ret[2]; +} + +int shmem_data_save(unsigned int msg, uint8_t *buffer, uint16_t real_len, uint32_t t_size, uint32_t s_size) +{ + unsigned int flash_start_addr; + unsigned int offset; + unsigned int poffset; + unsigned int psize; + unsigned char *buf; + unsigned int cached_size; + unsigned int wlen; + unsigned int wsize; + unsigned int section_idx; + + switch (msg) { + case REQ_CS_MSG: + section_idx = 0; + if (next_shmem_section[0].start + t_size + sizeof(shmem_section_data) < g_flash_cs_base + FLASH_CS_SIZE) { + flash_start_addr = next_shmem_section[0].start; + } else { + flash_start_addr = g_flash_cs_base; + } + next_shmem_section[0].start = flash_start_addr; + break; + case REQ_NV_MSG: + section_idx = 1; + if (next_shmem_section[1].start + t_size + sizeof(shmem_section_data) < g_flash_nv_base + FLASH_NV_SIZE) { + flash_start_addr = next_shmem_section[1].start; + } else { + flash_start_addr = g_flash_nv_base; + } + next_shmem_section[1].start = flash_start_addr; + break; + case REQ_CAL_MSG: + section_idx = 2; + if (next_shmem_section[2].start + t_size + sizeof(shmem_section_data) < g_flash_cal_base + FLASH_CAL_SIZE) { + flash_start_addr = next_shmem_section[2].start; + } else { + flash_start_addr = g_flash_cal_base; + } + next_shmem_section[2].start = flash_start_addr; + break; + default: + return -1; + } + + psize = up_progmem_blocksize(); + offset = s_size; + cached_size = s_size & (psize - 1); + wlen = 0; + + while (1) { + wsize = (real_len - wlen + cached_size > psize) ? psize - cached_size : real_len - wlen; + //printf("shmem_data_save:%d wsize : 0x%x cached_size : 0x%x real_len : 0x%x wlen : 0x%x psize : 0x%x buffer : 0x%x\n", __LINE__, wsize, cached_size, real_len, wlen, psize, buffer); + + if (wsize != psize) { + memcpy(save_cached + cached_size, buffer + wlen, wsize); + buf = save_cached; + } else { + buf = buffer + wlen; + } + cached_size += wsize; + wlen += wsize; + poffset = (offset / psize) * psize; + offset += wsize; + + //printf("shmem_data_save:%d wsize : 0x%x cached_size : 0x%x real_len : 0x%x wlen : 0x%x psize : 0x%x buf : 0x%x\n", __LINE__, wsize, cached_size, real_len, wlen, psize, buf); + + if (cached_size != psize) { + break; + } + + //printf("shmem_data_save addr(0x%08X) size(%X) buf(%p)\n", flash_start_addr + poffset, psize, buf); + cached_size = 0; + sflash_erase(flash_start_addr + poffset); + sflash_write(flash_start_addr + poffset, buf, psize); + } + + if (real_len + s_size >= t_size) { + poffset = (offset / psize) * psize; + //printf("shmem_data_save addr(0x%08X) size(%X) buf(%p)\n", flash_start_addr + poffset, cached_size, save_cached); + if (cached_size + sizeof(shmem_section_data) <= psize) { + memcpy(save_cached + 0xFF0, (unsigned char *)(&(next_shmem_section[section_idx])), 0x10); + sflash_erase(flash_start_addr + poffset); + sflash_write(flash_start_addr + poffset, save_cached, psize); + } else { + sflash_erase(flash_start_addr + poffset); + sflash_write(flash_start_addr + poffset, save_cached, cached_size); + //printf("shmem_data_save addr(0x%08X) size(%X) buf(%p)\n", flash_start_addr + poffset + psize, cached_size, save_cached); + memcpy(save_cached + 0xFF0, (unsigned char *)(&(next_shmem_section[section_idx])), 0x10); + sflash_erase(flash_start_addr + poffset + psize); + sflash_write(flash_start_addr + poffset, save_cached, psize); + } + } + + return 0; +} + +void shmem_factory_reset(void) +{ + unsigned int flash_start_addr; + unsigned int poffset = 0; + /* erase NV */ + flash_start_addr = g_flash_nv_base; + printf("erase NV [0x%x]\n", flash_start_addr); + for (poffset = 0; poffset < 64; poffset++) { + sflash_erase(flash_start_addr + poffset * 4096); + } + + /* erase CS */ + flash_start_addr = g_flash_cs_base; + printf("erase CS [0x%x]\n", flash_start_addr); + for (poffset = 0; poffset < 75; poffset++) { + sflash_erase(flash_start_addr + poffset * 4096); + } +} + +void shmem_save_read_cb(mio_buf *buf, void *data); +void shmem_initiate_cb(mio_buf *buf, void *data) +{ + save_cached = (unsigned char *)malloc(4096); + + shmem_mio->register_ReadCb(shmem_save_read_cb, NULL); + shmem_mio->write((char *)(&cur_save_target), 4); + free_mio_buf(buf); +} + +void shmem_save_read_cb(mio_buf *buf, void *data) +{ + uint16_t msg_len; + uint32_t remain_len, real_len; + uint8_t *buffer = (uint8_t *)(buf->data); + uint32_t total_size, sent_size; + unsigned long long nbsleep_sec; + + msg_len = *(uint16_t *)(buffer + 2); + + if (msg_len != 0) { + real_len = msg_len - 8; + total_size = *(uint32_t *)(buffer + 4); + sent_size = *(uint32_t *)(buffer + 8); + remain_len = *(uint32_t *)(buffer + 4) - *(uint32_t *)(buffer + 8); + + //printf("%s:%d cur_save_target(0x%08X) len(%x)\n", __func__, __LINE__, cur_save_target, buf->len); + //printf("msg_len : 0x%x t_size : 0x%x, s_size : 0x%x, real_len : 0x%x, remain_len : 0x%x\n", msg_len, total_size, sent_size, real_len, remain_len); + + shmem_data_save(cur_save_target, buffer + 12, real_len, total_size, sent_size); + } else { + //printf("%s:%d cur_save_target(0x%08X) len(%x)\n", __func__, __LINE__, cur_save_target, buf->len); + remain_len = 0; + real_len = 0; + } + + free_mio_buf(buf); + + if (remain_len == real_len) { + if (cur_save_target == REQ_CAL_MSG) { + free(save_cached); + cur_save_target = REQ_CS_MSG; + shmem_mio->register_ReadCb(shmem_initiate_cb, NULL); + nbsleep_req = 1; + nbsleep_sec = ((((unsigned long long)(getreg32(0x81000000 + 0xE4))) << 32) + getreg32(0x81000000 + 0xE8)) / 32768; + printf("\nEnter NB sleep!! %lld seconds\n", nbsleep_sec); + printf("\nOK\n"); + } + + cur_save_target += 0x10; + if (cur_save_target > REQ_CAL_MSG) { + cur_save_target = REQ_CS_MSG; + shmem_mio->register_ReadCb(shmem_initiate_cb, NULL); + } + } + + //printf("%s:%d cur_save_target(0x%08X)\n", __func__, __LINE__, cur_save_target); + shmem_mio->write((char *)(&cur_save_target), 4); +} + +extern "C" { + void shmem_save_init(void) + { + char mio_name[32] = "shmem_save"; + + cur_save_target = REQ_CS_MSG; + shmem_mio = getModemIoDeviceByName(mio_name); + shmem_mio->register_ReadCb(shmem_initiate_cb, NULL); + } + + void shmem_save_stop(void) + { + + } +} + + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.h new file mode 100644 index 0000000000..ba998e2238 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/modem/shmem_save.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __SHMEM_SAVE_H__ +#define __SHMEM_SAVE_H__ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +extern void shmem_save_task(void); +extern void shmem_factory_reset(void); +extern void shmem_get_data(unsigned int *cs, unsigned int *nv, unsigned int *cal); + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/objects.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/objects.h new file mode 100644 index 0000000000..7729175065 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/objects.h @@ -0,0 +1,136 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "i2c_def.h" +#include "spi_def.h" +#include "serial_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_dirclr; + __IO uint32_t *reg_out; + __IO uint32_t *reg_in; + PortName port; + uint32_t mask; +}; + +typedef enum { + USI0_PORT_ID = 0, + USI1_PORT_ID, + USI_MAX_PORTS +} t_usi_ports_enum; + +typedef enum { + PL011_UART0_ID = 0, + PL011_UART1_ID, + PL011_UART_MAX +} t_pl011_ports_enum; + +typedef enum { + DUMMY_UART0_ID = 0, + DUMMY_UART1_ID, + DUMMY_UART_MAX +} t_dummy_ports_enum; + + +struct uart_ops_s { + void (*serial_baud)(void *obj, int baudrate); + void (*serial_format)(void *obj, int data_bits, SerialParity parity, int stop_bits); + void (*serial_irq_handler)(void *obj, uart_irq_handler handler, uint32_t id); + void (*serial_irq_set)(void *obj, SerialIrq irq, uint32_t enable); + void (*serial_putc)(void *obj, int c); + int (*serial_writable)(void *obj); + int (*serial_getc)(void *obj); + int (*serial_readable)(void *obj); +#if DEVICE_SERIAL_FC + void (*serial_set_flow_control)(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow); +#endif +}; + + +struct serial_s { + void *uart; + int index; + int rx_fifo_depth; + int tx_fifo_depth; + struct uart_ops_s ops; +}; + +struct i2c_s { + I2C_TypeDef *i2c; + uint16_t last_xfer_address; + unsigned int xfer_speed; + unsigned int mode; + unsigned int base; + unsigned int timeout; + unsigned int slave_addr; + unsigned int addrlen; + unsigned int master; + int retries; + unsigned char initialized; + int clock; +}; + +struct spi_s { + SPI_TypeDef *spi; + unsigned int freqid; + unsigned int nbits; + unsigned int base; + unsigned int mode; + unsigned int frequency; + unsigned int actual; +}; + +struct analogin_s { + ADCName adc; + PinName pin; + uint32_t pin_number; + __IO uint32_t address; +}; + +struct flash_s { + uint32_t dummy; +}; + +struct trng_s { + uint32_t dummy; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/pinmap.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/pinmap.c new file mode 100644 index 0000000000..3ce7bd5a53 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/pinmap.c @@ -0,0 +1,33 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) +{ + MBED_ASSERT(pin != (PinName)NC); + +} + +void pin_mode(PinName pin, PinMode mode) +{ + MBED_ASSERT(pin != (PinName)NC); +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/port_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/port_api.c new file mode 100644 index 0000000000..f80143d554 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/port_api.c @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 ARM Limited + * + * 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. + */ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 : port_api.c + * @brief : GPIO port API source code + * @date : June 2019 + * + * @note : Add chip dependent feature and control hardware GPIO port + * + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) +{ + return (PinName)((port << PORT_SHIFT) | pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) +{ +#if 0//revise me + obj->port = port; + obj->mask = mask; + + CMSDK_GPIO_TypeDef *port_reg = + (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO0_BASE + ((int)port * 0x10)); + + obj->reg_in = &port_reg->DATAOUT; + obj->reg_dir = &port_reg->OUTENABLESET; + obj->reg_dirclr = &port_reg->OUTENABLECLR; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i = 0; i < 16; i++) { + if (obj->mask & (1 << i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +#endif +} + +void port_mode(port_t *obj, PinMode mode) +{ +#if 0//revise me + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i = 0; i < 32; i++) { + if (obj->mask & (1 << i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +#endif +} + +void port_dir(port_t *obj, PinDirection dir) +{ +#if 0//revise me + switch (dir) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +#endif +} + +void port_write(port_t *obj, int value) +{ + *obj->reg_in = value; +} + +int port_read(port_t *obj) +{ + return (*obj->reg_in); +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/rtc_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/rtc_api.c new file mode 100644 index 0000000000..c68699d303 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/rtc_api.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "mbed_assert.h" +#include "device.h" + +#if DEVICE_RTC +#include "rtc_api.h" +#include "mbed_mktime.h" +extern long long get_counter(void); +time_t g_base_timeval = 0; + +void rtc_init(void) +{ + +} + +void rtc_free(void) +{ + +} + +time_t rtc_read(void) +{ + time_t t; + long long cnt; + cnt = get_counter(); //return aliva countvalue in 40bits + t = cnt / 32768; //calculate as seconds + t += g_base_timeval; //accumulate base time(e.g., NTP) with counter elapsed. + + return t; +} + +void rtc_write(time_t t) +{ + g_base_timeval = t; +// printf("base time will be %d\n", g_base_timeval); +} + +static uint8_t rtc_hex8_to_dec(uint8_t hex_val) +{ + uint32_t calc_data; + + return (uint8_t)calc_data; +} + +static uint16_t rtc_hex16_to_dec(uint16_t hex_val) +{ + uint32_t calc_data; + return (uint16_t)calc_data; +} + +int rtc_isenabled(void) +{ + return 1; +} +#endif /* DEVICE_RTC */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.cpp b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.cpp new file mode 100644 index 0000000000..4b6c02c002 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.cpp @@ -0,0 +1,820 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "mbed.h" +#include "s5js100_dcxo.h" +#include "s5js100_type.h" + +#include "mbed_trace.h" +#define TRACE_GROUP "DCXO" + +#ifndef S5JS100_DCXO_DBG_ON +#define S5JS100_DCXO_DBG_ON 0 +#endif +#define S5JS100_DCXO_DBG if (S5JS100_DCXO_DBG_ON) tr_info + +#define DCXO_TEMPERATURE_RANGE 126 /* -40 ~ 85 */ +#define DCXO_TSU_TABLE_MIN_TEMPERATURE (-40) +#define DCXO_TSU_TABLE_MAX_TEMPERATURE 85 +#define DCXO_TSU_TABLE_MIN 10000 +#define DCXO_TSU_TABLE_LENGTH 35 +#define DCXO_TSU_TABLE_UNIT 5000 + +Thread *g_dcxo_tid; +static Semaphore dcxo_tbl_sem(1, 1); + +static unsigned int tsu_code_to_temperature(unsigned int tsu_code); +static unsigned int tsu_temperature_to_code(unsigned int temp_celcius); + +// table for KDS 9pF and SIDK board +// B constant : 3,380, T0 : 25'C +static const unsigned short g_dcxo_tsu_table[] = { + 49690, //-40'C, 10,000 + 48942, + 48194, //-30'C, 20,000 + 47446, + 46698, //-20'C, 30,000 + 45639, + 44316, //-10'C, 40,000 + 42776, + 41063, //0'C, 50,000 + 39214, + 37269, //10'C, 60,000 + 35261, + 33221, //20'C, 70,000 + 31177, + 29156, //30'C, 80,000 + 27180, + 25267, //40'C, 90,000 + 23436, + 21700, //50'C, 100,000 + 20069, + 18553, //60'C, 110,000 + 17155, + 15878, //70'C, 120,000 + 14721, + 13681, //80'C, 130,000 + 12751, + 11922, //90'C, 140,000 + 11181, + 10513, //100'C, 150,000 + 9899, + 9319, //110'C, 160,000 + 8749, + 8162, //120'C, 170,000 + 7527, + 6813, //130'C, 180,000 +}; + +static volatile int tsu_interrupt_flag; +static int dcxo_init_flag; +static Full_set_table_t *dcxo_tbl; + +// return value : (celcius temperature)*1000 + 50,000 +static unsigned int tsu_code_to_temperature(unsigned int tsu_code) +{ + unsigned int temp_code; + int index, base, ratio; + + index = 0; + + while (index < DCXO_TSU_TABLE_LENGTH) { + if (g_dcxo_tsu_table[index] <= tsu_code) { + break; + } else { + index++; + } + } + + if (index <= 0) { + index = 1; + } else if (index >= DCXO_TSU_TABLE_LENGTH) { + index = DCXO_TSU_TABLE_LENGTH - 1; + } + + base = (index - 1) * DCXO_TSU_TABLE_UNIT + DCXO_TSU_TABLE_MIN; + ratio = ((int)(g_dcxo_tsu_table[index - 1] - tsu_code) * DCXO_TSU_TABLE_UNIT) + / (int)(g_dcxo_tsu_table[index - 1] - g_dcxo_tsu_table[index]); + temp_code = base + ratio; + //dbg("\ng_dcxo_tsu_table[index]:%d, g_dcxo_tsu_table[index-1]:%d\n", g_dcxo_tsu_table[index], g_dcxo_tsu_table[index-1]); + //dbg("\nbase:%d, ratio:%d\n", base, ratio); + + return temp_code; +} + +// temp_celcius : (celcius temperature)*1000 + 50,000 +static unsigned int tsu_temperature_to_code(unsigned int temp_celcius) +{ + int index, ratio; + + index = (temp_celcius - DCXO_TSU_TABLE_MIN) / DCXO_TSU_TABLE_UNIT; + + if (temp_celcius <= DCXO_TSU_TABLE_MIN) { + index = 0; + ratio = (int)(DCXO_TSU_TABLE_MIN + DCXO_TSU_TABLE_UNIT * index - temp_celcius) * (int)(g_dcxo_tsu_table[index] - g_dcxo_tsu_table[index + 1]) / DCXO_TSU_TABLE_UNIT; + } else if (index >= DCXO_TSU_TABLE_LENGTH - 1) { + index = DCXO_TSU_TABLE_LENGTH - 1; + ratio = (int)(DCXO_TSU_TABLE_MIN + DCXO_TSU_TABLE_UNIT * index - temp_celcius) * (int)(g_dcxo_tsu_table[index - 1] - g_dcxo_tsu_table[index]) / DCXO_TSU_TABLE_UNIT; + } else { + ratio = (int)(DCXO_TSU_TABLE_MIN + DCXO_TSU_TABLE_UNIT * index - temp_celcius) * (int)(g_dcxo_tsu_table[index] - g_dcxo_tsu_table[index + 1]) / DCXO_TSU_TABLE_UNIT; + } + + //dbg("\nindex : %d , base : %d , ratio : %d\n", index, g_dcxo_tsu_table[index], ratio); + + return g_dcxo_tsu_table[index] + ratio; +} + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ +int dcxo_tsu_isr(int irq, void *context, void *arg) +{ + //dbg("%d, %d, %d\n", irq, context, arg); + NVIC_DisableIRQ((IRQn_Type)irq); + + //dbg("tsu_code : 0x%x, 0x%x, 0x%x, 0x%x\n", (getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA1) & 0xFFFF0000) >> 16, getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA1) & 0xFFFF, (getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA0) & 0xFFFF0000) >> 16, getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA0) & 0xFFFF); + + tsu_interrupt_flag = 1; + + if (irq == S5JS100_IRQ_TSU0) { + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 1); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 0x10, 0x10); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF, 0x0); + //dbg("TSU0 interrupt\n"); + } else if (irq == S5JS100_IRQ_TSU1) { + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 2); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 0x20, 0x20); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF0000, 0xFFFF0000); + //dbg("TSU1 interrupt\n"); + } + + return 0; +} + + + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: s5js100_dcxo_ctb_loop + * + * Description: + * update DCXO value in every ms by parameter freq + * + * Returned Value: + * a NULL on failure + * + ****************************************************************************/ +int s5js100_dcxo_tbl_dump(void) +{ + int i; + for (i = 0; i < DCXO_TEMPERATURE_RANGE; i++) { + S5JS100_DCXO_DBG("%d : CTB[%d]", i - 40, (dcxo_tbl + i)->ctb); + } + return 0; +} + +void dcxo_ctb_sem_wait(void) +{ + dcxo_tbl_sem.try_acquire(); +} + +void dcxo_ctb_sem_release(void) +{ + dcxo_tbl_sem.release(); +} + +void s5js100_dcxo_ctb_loop(void) +{ + int tsu, index, ctb, ctb_prev; + int ctb_gap; + int loop_started = 0; + + //s5js100_dcxo_tbl_dump(); + + while (1) { + // refer dcxo table + // read TSU + tsu = (int) s5js100_tsu_get_temperature(); + index = (tsu - 10000) / 1000; + + dcxo_ctb_sem_wait(); + + if (tsu < (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000)) { + index = 0; + ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb; + ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000))) / 1000; + } else if (tsu > (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000)) { + index = DCXO_TEMPERATURE_RANGE - 1; + ctb_gap = dcxo_tbl[index].ctb - dcxo_tbl[index - 1].ctb; + ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000))) / 1000; + } else { + ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb; + ctb = dcxo_tbl[index].ctb + ctb_gap * (tsu % 1000) / 1000; + } + + if (ctb < 0) { + ctb = 0; + } else if (ctb > 16383) { + ctb = 16383; + } + + if (!loop_started) { + S5JS100_DCXO_DBG("s5js100_dcxo_ctb_loop FIRST update temp(%d) coarse(%d -> %d)", tsu - 50000, s5js100_dcxo_get_coarse_tune_value, ctb); + s5js100_dcxo_set_tune_value(ctb, 4096); + } else { + ctb_prev = s5js100_dcxo_get_coarse_tune_value(); + + if (ctb > ctb_prev) { + ctb_prev++; + } else if (ctb < ctb_prev) { + ctb_prev--; + } + s5js100_dcxo_set_tune_value(ctb_prev, 4096); + //dcxollvdbg("[ctb_cal:%d, ctb_set:%d]\n", ctb, ctb_prev); + } + + if (ctb == 0) { + S5JS100_DCXO_DBG("[ERROR]CTB was 0x0[temp:%d]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", tsu); + //asm("b ."); + } + +#if 0 + if ((tsu - 50000) > 0) { + //printf("TSU : %d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (tsu) % 1000, ctb, tsu); + } else if ((tsu - 50000) > -1000) { + //printf("TSU : -%d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (1000 - (tsu) % 1000) % 1000, ctb, tsu); + } else { + //printf("TSU : %d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (1000 - (tsu) % 1000) % 1000, ctb, tsu); + } +#endif + loop_started = 1; + dcxo_ctb_sem_release(); + osDelay(50); + } +} + +int s5js100_tsu_get_code(void) +{ + return (getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA0) & 0xFFFF); +} + +int s5js100_dcxo_force_update_ctb(void) +{ + int tsu, index, ctb, code; + int ctb_gap; + + // read TSU + code = s5js100_tsu_get_code(); + tsu = (int) tsu_code_to_temperature(code); + + index = (tsu - 10000) / 1000; + + if (tsu < (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000)) { + index = 0; + ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb; + ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000))) / 1000; + } else if (tsu > (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000)) { + index = DCXO_TEMPERATURE_RANGE - 1; + ctb_gap = dcxo_tbl[index].ctb - dcxo_tbl[index - 1].ctb; + ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000))) / 1000; + } else { + ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb; + ctb = dcxo_tbl[index].ctb + ctb_gap * (tsu % 1000) / 1000; + } + + if (ctb < 0) { + ctb = 0; + } else if (ctb > 16383) { + ctb = 16383; + } + + s5js100_dcxo_set_tune_value(ctb, 4096); + + if (ctb == 0) { + S5JS100_DCXO_DBG("Force CTB was 0x0[temp:%d, code:%d]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", tsu, code); + //asm("b ."); + } + + if ((tsu - 50000) > 0) { + //dcxollvdbg("TSU : %d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (tsu) % 1000, ctb, tsu); + } else if ((tsu - 50000) > -1000) { + //dcxollvdbg("TSU : -%d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (1000 - (tsu) % 1000) % 1000, ctb, tsu); + } else { + //dcxollvdbg("TSU : %d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (1000 - (tsu) % 1000) % 1000, ctb, tsu); + } + + return 0; +} + + + + +/**************************************************************************** + * Name: s5js100_dcxo_initialize + * + * Description: + * Initialize the DCXO. + * + * Returned Value: + * a NULL on failure + * + ****************************************************************************/ +int s5js100_dcxo_initialize(void) +{ + if (dcxo_init_flag == 0) { + // initialize DOTSU, clk:100kHz + //putreg32(0x3E5, S5JS100_DCXO_CFG + DCXO_CFG_ADC_CFG); + //putreg32(0x1BE7, S5JS100_DCXO_CFG + DCXO_CFG_ADC_CFG); //ATE setting value + putreg32(0x13FE5, S5JS100_DCXO_CFG + DCXO_CFG_ADC_CFG); //Final setting value + putreg32(0x3A, S5JS100_DCXO_CFG + DCXO_CFG_DIV_CFG); + putreg32(0x30, S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1); + putreg32(0xFFFF0000, S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0); + + // tsu sensing time by average unit + // 0:10us, 1:40us, 2:160us, 3:640us, 4:2.56ms, 5:10.24ms, 6:81.92ms, 7:327.68 ms + putreg32(0x3, S5JS100_DCXO_CFG + DCXO_CFG_AVR_CFG); + //putreg32(0x7, S5JS100_DCXO_CFG + DCXO_CFG_AVR_CFG); + + // wait till update temperature + while (!(getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA1) & 0xFFFF0000)) { + } + + // initialize DCXO + // IDAC_SEL = 1 + modifyreg32(S5JS100_PMU_ALIVE + 0x520, 1 << 3, 1 << 3); + +#if 0 + // IDAC_EX = 0xa0 + modifyreg32(S5JS100_PMU_ALIVE + 0x524, 0xff << 5, 0xa0 << 5); +#else + // change tune parameter + // IDAC_EX = 100 + modifyreg32(S5JS100_PMU_ALIVE + 0x524, 0xff << 5, 100 << 5); + + // BUF_SEL = 8 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0xf << 3, 8 << 3); +#endif + +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + // Fine=FTUNE2, Coarse=DcxoFTune + // FuneMuxSel = 1 + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 1, 1); + + // FTSEL = 1 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 16, 1 << 16); + + // FTSWP = 1 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 15, 1 << 15); + +#elif defined(DCXO_FINE_PMU_COARSE_PMU) + // Fine=FTUNE2, Coarse=FTUNE + // FuneMuxSel = 0 + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 1, 0); + + // FTSEL = 1 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 16, 1 << 16); + + // FTSWP = 1 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 15, 1 << 15); +#elif defined(DCXO_FINE_DCXO_COARSE_PMU) + // Fine=DcxoFTune, Coarse=FTUNE2 + // FuneMuxSel = 1 + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 1, 1); + + // FTSEL = 1 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 16, 1 << 16); + + // FTSWP = 0 + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 15, 0); +#endif + dcxo_init_flag = 1; + } + + return 1; +} + +int s5js100_dcxo_start_ctb_loop(Full_set_table_t tbl[]) +{ + dcxo_tbl = tbl; + + g_dcxo_tid = new rtos::Thread(osPriorityNormal, 2048, NULL, "ctbloop"); + g_dcxo_tid->start(s5js100_dcxo_ctb_loop); + + if (!g_dcxo_tid) { + return -ESRCH; + } + + return 0; +} + +int s5js100_dcxo_stop_ctb_loop(void) +{ +// if(!task_delete(g_dcxo_tid)){ +// lldbg("fail to delete ctb_loop task ..\n"); +// } +// else +// lldbg("ctb_loop stopped..\n"); + + return 0; +} + +/**************************************************************************** + * Name: s5js100_tsu_get_temperature + * + * Description: + * Read temperature of TSX. + * + * Returned Value: + * celcius temperature + * + ****************************************************************************/ +int s5js100_tsu_calculate_temperature(unsigned int code) +{ + return tsu_code_to_temperature(code); +} + +int s5js100_tsu_convert_code(unsigned int temperature) +{ + return tsu_temperature_to_code(temperature); +} + +int s5js100_tsu_get_temperature(void) +{ + return tsu_code_to_temperature(s5js100_tsu_get_code()); +} + +int s5js100_tsu_set_interrupt(int high_interrupt, int temp) +{ + unsigned int tsu_code, irq_no; + + if (temp < DCXO_TSU_TABLE_MIN_TEMPERATURE) { + temp = DCXO_TSU_TABLE_MIN_TEMPERATURE; + } else if (temp > DCXO_TSU_TABLE_MIN_TEMPERATURE + DCXO_TSU_TABLE_LENGTH - 1) { + temp = DCXO_TSU_TABLE_MIN_TEMPERATURE + DCXO_TSU_TABLE_LENGTH - 1; + } + + if (high_interrupt) { + tsu_code = tsu_temperature_to_code(temp - 1); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 1); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF, tsu_code); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 4), 0); + irq_no = S5JS100_IRQ_TSU0; + } else { + tsu_code = tsu_temperature_to_code(temp); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 2); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF0000, tsu_code << 16); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 5), 0); + irq_no = S5JS100_IRQ_TSU1; + } + + //dbg("\ns5js100_tsu_set_interrupt(%d), tsu_code : 0x%x", high_interrupt, tsu_code); + + NVIC_SetVector((IRQn_Type)irq_no, (uint32_t)dcxo_tsu_isr); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + NVIC_EnableIRQ((IRQn_Type)irq_no); + + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), (1 << 2)); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), 0); + + return 1; +} + +int s5js100_tsu_set_interrupt_code(int high_interrupt, int tsu_code, int check) +{ + unsigned int irq_no; + int ret = 1; + + //dbg("s5js100_tsu_set_interrupt(%d), tsu_code : 0x%x\n", high_interrupt, tsu_code); + + if (check) { + tsu_interrupt_flag = 0; + } + + if (!high_interrupt) { + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 1); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF, tsu_code); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 4), 0); + irq_no = S5JS100_IRQ_TSU0; + } else { + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 2); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF0000, tsu_code << 16); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 5), 0); + irq_no = S5JS100_IRQ_TSU1; + } + + NVIC_SetVector((IRQn_Type)irq_no, (uint32_t)dcxo_tsu_isr); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + NVIC_EnableIRQ((IRQn_Type)irq_no); + + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), (1 << 2)); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), 0); + + if (check) { + //sleep(1); + + if (!tsu_interrupt_flag) { + ret = 0; + } + } + + return ret; +} + +int s5js100_dcxo_get_coarse_tune_value(void) +{ + int coarse_tune; + +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + // Fine=DcxoFTune, Coarse=FTUNE2 + coarse_tune = (getreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0) >> 1) & 0xFFFFF; + coarse_tune >>= 6; +#elif defined(DCXO_FINE_PMU_COARSE_PMU) + // Fine=FTUNE2, Coarse=FTUNE + + // Coarse=FTUNE 14bit + // EVT0 : 0x81000524[26:13], EVT1 : 0x8100000C[13:0] + if (is_evt0()) { + coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0x524) >> 13) & 0x3FFF; + } else { + coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0xC) >> 0) & 0x3FFF; + } +#elif defined(DCXO_FINE_DCXO_COARSE_PMU) + // Fine=DcxoFTune, Coarse=FTUNE2 + + // Coarse=FTUNE2 14bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + if (is_evt0()) { + coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0x528) >> 17) & 0x3FFF; + } else { + coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0xC) >> 14) & 0x3FFF; + } +#endif + + return coarse_tune; +} + + +int s5js100_dcxo_set_tune_value(unsigned int coarse_value, unsigned int fine_value) +{ +// printf("%s, coarse_value : 0x%x, fine_value : 0x%x\n", __func__, coarse_value, fine_value); + +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + // Fine=DcxoFTune, Coarse=FTUNE2 + coarse_value <<= 6; + + // Coarse = DcxoFTune 20bit + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, coarse_value << 1); + + // Fine=FTUNE2 14bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14); + } +#elif defined(DCXO_FINE_PMU_COARSE_PMU) + // Fine=FTUNE2, Coarse=FTUNE + + // Fine = FTUNE2 13bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14); + } + + // Coarse=FTUNE 14bit + // EVT0 : 0x81000524[26:13], EVT1 : 0x8100000C[13:0] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x524, (0x3FFF << 13), (coarse_value << 13)); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 0, coarse_value << 0); + } +#elif defined(DCXO_FINE_DCXO_COARSE_PMU) + // Fine=DcxoFTune, Coarse=FTUNE2 + fine_value <<= 6; + + // Fine = DcxoFTune 20bit + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, fine_value << 1); + + // Coarse=FTUNE2 14bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, coarse_value << 17); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, coarse_value << 14); + } +#endif + + //printf("dotsu : %d\n", s5js100_tsu_get_code()); + + return 1; +} + +int s5js100_dcxo_set_tune_value_20bit(unsigned int coarse_value, unsigned int fine_value) +{ + //printf("%s, coarse_value : 0x%x, fine_value : 0x%x\n", __func__, coarse_value, fine_value); + +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + // Coarse=DcxoFTune, Fine=FTUNE2 + + // Coarse = DcxoFTune 20bit + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, coarse_value << 1); + + // Fine=FTUNE2 14bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14); + } + + // toggle oSwRstDSM + //modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1<<3), 0); + //modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1<<3), (1<<3)); +#elif defined(DCXO_FINE_PMU_COARSE_PMU) + // Fine=FTUNE2, Coarse=FTUNE + + coarse_value >>= 6; + //printf("coarse_value changed to 14 bit (0x%x)\n", coarse_value); + + // Fine = FTUNE2 13bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14); + } + + // Coarse=FTUNE 14bit + // EVT0 : 0x81000524[26:13], EVT1 : 0x8100000C[13:0] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x524, (0x3FFF << 13), (coarse_value << 13)); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 0, coarse_value << 0); + } +#elif defined(DCXO_FINE_DCXO_COARSE_PMU) + // Fine=DcxoFTune, Coarse=FTUNE2 + + coarse_value >>= 6; + //printf("coarse_value changed to 14 bit (0x%x)\n", coarse_value); + + // Fine = DcxoFTune 20bit + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, fine_value << 1); + + // Coarse=FTUNE2 14bit + // EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14] + if (is_evt0()) { + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, coarse_value << 17); + } else { + modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, coarse_value << 14); + } +#endif + + return 1; +} + +int s5js100_dcxo_set_idac_ex(int value) +{ + modifyreg32(S5JS100_PMU_ALIVE + 0x524, 0xff << 5, value << 5); + return 1; +} + +int s5js100_dcxo_set_fb_res(int value) +{ + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x7 << 0, value << 0); + return 1; +} + +int s5js100_dcxo_set_buf_sel(int value) +{ + modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0xf << 3, value << 3); + return 1; +} + +int s5js100_dcxo_set_dsmdither(unsigned int dither_bit_sel) +{ +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + // set dither_bit_sel, iDsmType=1, iEnDsmDither=0, iPrbsSel=0, iEnDsm=1 + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, 0x7F, (1 << 6) + (dither_bit_sel << 2) + 1); + + // toggle oSwRstDSM + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3)); +#else + //printf("To enable dsm dither, DCXO option should be changed to DCXO_FINE_PMU_COARSE_DCXO\n" +#endif + return 1; +} + +int s5js100_dcxo_set_dither_bit_sel(unsigned int dither_bit_sel) +{ +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (7 << 2), (dither_bit_sel << 2)); + // toggle oSwRstDSM + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3)); +#else + //printf("DCXO option should be changed to DCXO_FINE_PMU_COARSE_DCXO\n" +#endif + return 1; +} + +int s5js100_dcxo_set_dsm_type(unsigned int dsm_type) +{ +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 6), (dsm_type << 6)); + // toggle oSwRstDSM + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3)); +#else + //printf("DCXO option should be changed to DCXO_FINE_PMU_COARSE_DCXO\n" +#endif + return 1; +} + +int s5js100_dcxo_set_en_dsm_dither(unsigned int en_dsm_dither) +{ +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 5), (en_dsm_dither << 5)); + // toggle oSwRstDSM + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3)); +#else + //printf("DCXO option should be changed to DCXO_FINE_PMU_COARSE_DCXO\n" +#endif + return 1; +} + +int s5js100_dcxo_set_prbs_sel(unsigned int prbs_sel) +{ +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 1), (prbs_sel << 1)); + // toggle oSwRstDSM + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3)); +#else + //printf("DCXO option should be changed to DCXO_FINE_PMU_COARSE_DCXO\n" +#endif + return 1; +} + +int s5js100_dcxo_en_dsm(unsigned int en_dsm) +{ +#if defined(DCXO_FINE_PMU_COARSE_DCXO) + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 0), (en_dsm << 0)); + // toggle oSwRstDSM + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0); + modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3)); +#else + //printf("DCXO option should be changed to DCXO_FINE_PMU_COARSE_DCXO\n" +#endif + return 1; +} + +extern "C" { + int s5js100_dcxo_force_initialize(void) + { + dcxo_init_flag = 0; + s5js100_dcxo_initialize(); + s5js100_dcxo_force_update_ctb(); + + return 0; + } +} diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.h new file mode 100644 index 0000000000..97957dff7a --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_dcxo.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5SJ100_DCXO_H__ +#define __S5SJ100_DCXO_H__ + +// default option +#define DCXO_FINE_PMU_COARSE_DCXO 1 +//#define DCXO_FINE_PMU_COARSE_PMU 0 +//#define DCXO_FINE_DCXO_COARSE_PMU 0 + + +// SFR base +#define S5JS100_EFUSE 0x82010000 +#define S5JS100_DCXO_CFG 0x87000000 +#define S5JS100_PMU_ALIVE 0x81000000 + +// SFR offset (DCXO) +#define DCXO_CFG_SW_RESETN 0x0 +#define DCXO_CFG_DIV_CFG 0x4 +#define DCXO_CFG_DSM_CFG0 0x8 +#define DCXO_CFG_DSM_CFG1 0xC +#define DCXO_CFG_AVR_CFG 0x10 +#define DCXO_CFG_IRQ_CFG0 0x14 +#define DCXO_CFG_IRQ_CFG1 0x18 +#define DCXO_CFG_IRQ_STA0 0x1C +#define DCXO_CFG_IRQ_STA1 0x20 +#define DCXO_CFG_ADC_CFG 0x24 + +// SFR offset (PMU_Alive) +#define DCXO_Cfg0 0x520 +#define DCXO_Cfg1 0x524 +#define DCXO_Cfg2 0x528 +#define DCXO_Cfg3 0x52C + + +/* DCXO FRAME MSG TYPE */ +#define DCXO_CTB_FULLSET_UPDATE 0x1 +#define DCXO_TEMP_REQUEST 0x2 +#define DCXO_CTB_FORCE_REQUEST_FOR_FACTORY_CAL 0x3 +#define DCXO_GET_CTB_REQUEST 0x4 +#define DCXO_GET_TSX_INFO_REQUEST 0x5 + +#define DCXO_RESPONSE_ACK 0xDC10 +#define DCXO_RESPONSE_NCK 0xDEAD + +#define DCXO_TEMPERATURE_RANGE 126 /* -40 ~ 85 */ + +#if defined(CONFIG_S5JS100_TSX_KDS) +#define S5JS100_TSX_TYPE 0x1 +#elif defined(CONFIG_S5JS100_TSX_NDK) +#define S5JS100_TSX_TYPE 0x2 +#elif defined(CONFIG_S5JS100_TSX_KYOCERA) +#define S5JS100_TSX_TYPE 0x3 +#endif + +#ifndef S5JS100_TSX_TYPE +#define S5JS100_TSX_TYPE 0x1 +#endif + + +typedef struct { + unsigned short ctb; + unsigned short reserved; +} Full_set_table_t; + +typedef struct { + unsigned int msgType; + int response; + int response1; +} UpdateInd_header_t; + +typedef struct { + unsigned int resolution; + int start_temp; + unsigned int length; + Full_set_table_t setTable[DCXO_TEMPERATURE_RANGE]; +} UpdateInd_payload_t; + +typedef struct { + UpdateInd_header_t header; + UpdateInd_payload_t payload; +} Nl1cHiu_UpdateInd_t; + +extern int s5js100_dcxo_start_ctb_loop(Full_set_table_t tbl[]); +extern int s5js100_dcxo_stop_ctb_loop(void); +extern int s5js100_dcxo_set_tune_value(unsigned int coarse_value, unsigned int fine_value); +extern int s5js100_tsu_get_temperature(void); +extern int s5js100_dcxo_get_coarse_tune_value(void); + +extern void dcxo_ctb_sem_wait(void); +extern void dcxo_ctb_sem_release(void); + +extern "C" { + int s5js100_dcxo_initialize(void); +} + +#endif /* __S5SJ100_DCXO_H__ */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_error.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_error.h new file mode 100644 index 0000000000..ad045160cd --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_error.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_ERROR_H__ +#define __S5JS100_ERROR_H__ + +#include + +#ifndef S5JS100_ERROR_RETUN_LOG +#define S5JS100_ERROR_RETUN_LOG 0 +#endif + +#ifdef S5JS100_ERROR_IS_HALT +#define return_error(ret) { \ + if (S5JS100_ERROR_RETUN_LOG) printf("S5JS100 HALT!!! %s:%d:%s\n", __FILE__, __LINE__, __func__); \ + while(1); \ + return ret; } +#else +#define return_error(ret) { \ + if (S5JS100_ERROR_RETUN_LOG) printf("Return Error %s:%d:%s ret_value=0x%p\n", __FILE__, __LINE__, __func__, (void *)ret); \ + return ret; } +#endif + +//#define system_halt() reboot() +#define system_halt() { \ + if (S5JS100_ERROR_RETUN_LOG) printf("S5JS100 HALT!!! %s:%d:%s\n", __FILE__, __LINE__, __func__); \ + while(1); } + +/* Error code */ +#undef EINVAL +#define EINVAL 22 /* Invalid argument */ + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pinconfig.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pinconfig.h new file mode 100644 index 0000000000..abf9270aec --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pinconfig.h @@ -0,0 +1,294 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __ARCH_ARM_SRC_S5JS100_CHIP_S5JS100_PINCONFIG_H__ +#define __ARCH_ARM_SRC_S5JS100_CHIP_S5JS100_PINCONFIG_H__ +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* GPIO pin definitions *****************************************************/ + +#define GPIO_DEFAULT_CONFIG (GPIO_GPIO|GPIO_PULLUP|GPIO_INPUT|GPIO_OUTPUT|GPIO_FAST1X) + +#define GPIO_GPIO0 (GPIO_DEFAULT_CONFIG | GPIO_PIN0) +#define GPIO_EXT_LNA_ON0 (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN0) +#define GPIO_MCP_SM_CE (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN0) + +#define GPIO_GPIO1 (GPIO_DEFAULT_CONFIG | GPIO_PIN1) +#define GPIO_EXT_LNA_ON1 (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN1) +#define GPIO_MCP_SM_UB (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN1) + +#define GPIO_GPIO2 (GPIO_DEFAULT_CONFIG | GPIO_PIN2) +#define GPIO_EXT_LNA_GNSS (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN2) +#define GPIO_MCP_SM_LB (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN2) + +#define GPIO_GPIO3 (GPIO_DEFAULT_CONFIG | GPIO_PIN3) +#define GPIO_PA_MODE0 (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN3) + +#define GPIO_GPIO4 (GPIO_DEFAULT_CONFIG | GPIO_PIN4) +#define GPIO_PA_MODE1 (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN4) + +#define GPIO_GPIO5 (GPIO_DEFAULT_CONFIG | GPIO_PIN5) +#define GPIO_PA_ON0 (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN5) + +#define GPIO_GPIO6 (GPIO_DEFAULT_CONFIG | GPIO_PIN6) +#define GPIO_PA_ON1 (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN6) + +#define GPIO_GPIO7 (GPIO_DEFAULT_CONFIG | GPIO_PIN7) +#define GPIO_ACMU_MON_CLK (GPIO_ALT0 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN7) +#define GPIO_MCMU_MON_CLK (GPIO_ALT1 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN7) +#define GPIO_MIFCMU_MON_CLK (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN7) +#define GPIO_SCMU_MON_CLK (GPIO_ALT3 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN7) +#define GPIO_MDM_PLL_MON_CLK (GPIO_ALT4 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN7) +#define GPIO_NBIOT_MON_CLK (GPIO_ALT5 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN7) + + +#define GPIO_GPIO8 (GPIO_DEFAULT_CONFIG | GPIO_PIN8) +#define GPIO_USI0_RXD_CLK_SCL (GPIO_ALT1 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN8) +#define GPIO_MCP_SM_CRE (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN8) + +#define GPIO_GPIO9 (GPIO_DEFAULT_CONFIG | GPIO_PIN9) +#define GPIO_USI0_TXD_MOSI_SDA (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST1X | GPIO_PIN9) +#define GPIO_MCP_FH_RST (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN9) + + +#define GPIO_GPIO10 (GPIO_DEFAULT_CONFIG | GPIO_PIN10) +#define GPIO_USI0_RTSN_MISO_NA (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST1X | GPIO_PIN10) +#define GPIO_MCP_RDY_WAIT (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN10) + +#define GPIO_GPIO11 (GPIO_DEFAULT_CONFIG | GPIO_PIN11) +#define GPIO_USI0_CTSN_CSN_NA (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST1X | GPIO_PIN11) +#define GPIO_MCP_A23 (GPIO_ALT6 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN11) + +#define GPIO_GPIO12 (GPIO_DEFAULT_CONFIG | GPIO_PIN12) +#define GPIO_USI1_RXD_CLK_SCL (GPIO_ALT1 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN12) +#define GPIO_USIM0_DETECT (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN12) + +#define GPIO_GPIO13 (GPIO_DEFAULT_CONFIG | GPIO_PIN13) +#define GPIO_USI1_TXD_MOSI_SDA (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST1X | GPIO_PIN13) +#define GPIO_APT_PDM (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN13) + +#define GPIO_GPIO14 (GPIO_DEFAULT_CONFIG | GPIO_PIN14) +#define GPIO_USI1_RTSN_MISO_NA (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST1X | GPIO_PIN14) +#define GPIO_GPS_TIMESTAMP (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN14) +#define GPIO_PWM_TOUT0 (GPIO_ALT3 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN14) + +#define GPIO_GPIO15 (GPIO_DEFAULT_CONFIG | GPIO_PIN15) +#define GPIO_USI1_CTSN_CSN_NA (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST1X | GPIO_PIN15) +#define GPIO_GPS_PAEN (GPIO_ALT2 | GPIO_PULLDOWN | GPIO_FAST1X | GPIO_PIN15) +#define GPIO_PWM_TOUT1 (GPIO_ALT3 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN15) + +#define GPIO_GPIO16 (GPIO_DEFAULT_CONFIG | GPIO_PIN16) +#define GPIO_UART0_CTSB (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN16) + + +#define GPIO_GPIO17 (GPIO_DEFAULT_CONFIG | GPIO_PIN17) +#define GPIO_UART0_RTSB (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN17) + +#define GPIO_GPIO18 (GPIO_DEFAULT_CONFIG | GPIO_PIN18) +#define GPIO_UART1_CTSB (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN18) +#define GPIO_SDIO_DATA0 (GPIO_ALT2 | GPIO_PULLUP | GPIO_OUTPUT| GPIO_FAST3X | GPIO_PIN18) + +#define GPIO_GPIO19 (GPIO_DEFAULT_CONFIG | GPIO_PIN19) +#define GPIO_UART1_RTSB (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN19) +#define GPIO_SDIO_DATA1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_OUTPUT| GPIO_FAST3X | GPIO_PIN19) +#define GPIO_GNSS_DEBUG0 (GPIO_ALT4 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN19) + +#define GPIO_GPIO20 (GPIO_DEFAULT_CONFIG | GPIO_PIN20) +#define GPIO_SDIO_DATA2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_OUTPUT| GPIO_FAST3X | GPIO_PIN20) +#define GPIO_GNSS_DEBUG1 (GPIO_ALT4 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN20) + +#define GPIO_GPIO21 (GPIO_DEFAULT_CONFIG | GPIO_PIN21) +#define GPIO_SDIO_DATA3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_OUTPUT| GPIO_FAST3X | GPIO_PIN21) +#define GPIO_GNSS_DEBUG2 (GPIO_ALT4 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN21) + +#define GPIO_GPIO22 (GPIO_DEFAULT_CONFIG | GPIO_PIN22) +#define GPIO_PWM_TOUT2 (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN22) +#define GPIO_SDIO_CLK (GPIO_ALT2 | GPIO_PULLUP | GPIO_OUTPUT| GPIO_FAST3X | GPIO_PIN22) +#define GPIO_GNSS_DEBUG3 (GPIO_ALT4 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN22) + +#define GPIO_GPIO23 (GPIO_DEFAULT_CONFIG | GPIO_PIN23) +#define GPIO_PWM_TOUT3 (GPIO_ALT1 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN23) +#define GPIO_SDIO_CMD (GPIO_ALT2 | GPIO_PULLUP | GPIO_OUTPUT| GPIO_FAST3X | GPIO_PIN23) +#define GPIO_GNSS_DEBUG4 (GPIO_ALT4 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN23) + +#define GPIO_GPIO24 (GPIO_DEFAULT_CONFIG | GPIO_PIN24) +#define GPIO_USIM0_CLK (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN24) + +#define GPIO_GPIO25 (GPIO_DEFAULT_CONFIG | GPIO_PIN25) +#define GPIO_USIM0_DATA (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN25) + +#define GPIO_GPIO26 (GPIO_DEFAULT_CONFIG | GPIO_PIN26) +#define GPIO_USIM0_RST (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN26) + +#define GPIO_GPIO27 (GPIO_DEFAULT_CONFIG | GPIO_PIN27) +#define GPIO_UART0_RXD (GPIO_ALT0 | GPIO_PULLDOWN | GPIO_FAST3X | GPIO_PIN27) + +#define GPIO_GPIO28 (GPIO_DEFAULT_CONFIG | GPIO_PIN28) +#define GPIO_UART0_TXD (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN28) + +#define GPIO_GPIO29 (GPIO_DEFAULT_CONFIG | GPIO_PIN29) +#define GPIO_UART1_RXD (GPIO_ALT0 | GPIO_PULLDOWN | GPIO_FAST3X | GPIO_PIN29) + +#define GPIO_GPIO30 (GPIO_DEFAULT_CONFIG | GPIO_PIN30) +#define GPIO_UART1_TXD (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN30) + +#define GPIO_GPIO31 (GPIO_DEFAULT_CONFIG | GPIO_PIN31) +#define GPIO_SPI0_RXD (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN31) + +#define GPIO_GPIO32 (GPIO_DEFAULT_CONFIG | GPIO_PIN32) +#define GPIO_SPI0_TXD (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN32) + +#define GPIO_GPIO33 (GPIO_DEFAULT_CONFIG | GPIO_PIN33) +#define GPIO_SPI0_CLK (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN33) + +#define GPIO_GPIO34 (GPIO_DEFAULT_CONFIG | GPIO_PIN34) +#define GPIO_SPI0_CS (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN34) + +#define GPIO_GPIO35 (GPIO_DEFAULT_CONFIG | GPIO_PIN35) +#define GPIO_I2C0_SCL (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN35) + +#define GPIO_GPIO36 (GPIO_DEFAULT_CONFIG | GPIO_PIN36) +#define GPIO_I2C0_SDA (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN36) + +#define GPIO_GPIO37 (GPIO_DEFAULT_CONFIG | GPIO_PIN37) +#define GPIO_CS (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN37) +#define GPIO_MCP_FH_CE (GPIO_ALT6 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN37) + +#define GPIO_GPIO38 (GPIO_DEFAULT_CONFIG | GPIO_PIN38) +#define GPIO_SCK (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN38) +#define GPIO_MCP_CLK (GPIO_ALT6 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN38) + +#define GPIO_GPIO39 (GPIO_DEFAULT_CONFIG | GPIO_PIN39) +#define GPIO_SI (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN39) +#define GPIO_MCP_FBCLK (GPIO_ALT6 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN39) + +#define GPIO_GPIO40 (GPIO_DEFAULT_CONFIG | GPIO_PIN40) +#define GPIO_SO (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN40) +#define GPIO_MCP_OE (GPIO_ALT6 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN40) + +#define GPIO_GPIO41 (GPIO_DEFAULT_CONFIG | GPIO_PIN41) +#define GPIO_WP (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN41) +#define GPIO_MCP_WE (GPIO_ALT6 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN41) + + +#define GPIO_GPIO42 (GPIO_DEFAULT_CONFIG | GPIO_PIN42) +#define GPIO_HLD (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN42) +#define GPIO_MCP_ADV (GPIO_ALT6 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN42) + +#define GPIO_GPIO43 (GPIO_DEFAULT_CONFIG | GPIO_PIN43) +#define GPIO_ANT_SW0 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN43) + +#define GPIO_GPIO44 (GPIO_DEFAULT_CONFIG | GPIO_PIN44) +#define GPIO_ANT_SW1 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN44) + +#define GPIO_GPIO45 (GPIO_DEFAULT_CONFIG | GPIO_PIN45) +#define GPIO_ANT_SW2 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN45) + +#define GPIO_GPIO46 (GPIO_DEFAULT_CONFIG | GPIO_PIN46) +#define GPIO_ANT_SW3 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN46) + +#define GPIO_GPIO46 (GPIO_DEFAULT_CONFIG | GPIO_PIN46) +#define GPIO_ANT_SW3 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN46) + +#define GPIO_GPIO47 (GPIO_DEFAULT_CONFIG | GPIO_PIN47) +#define GPIO_ANT_SW4 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN47) + +#define GPIO_GPIO48 (GPIO_DEFAULT_CONFIG | GPIO_PIN48) +#define GPIO_MIPI_RFFE_SCLK (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN48) + +#define GPIO_GPIO49 (GPIO_DEFAULT_CONFIG | GPIO_PIN49) +#define GPIO_MIPI_RFFE_DATA (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN49) + +#define GPIO_GPIO50 (GPIO_DEFAULT_CONFIG | GPIO_PIN50) +#define GPIO_MCP_ADQ0 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN50) + +#define GPIO_GPIO51 (GPIO_DEFAULT_CONFIG | GPIO_PIN51) +#define GPIO_MCP_ADQ1 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN51) + +#define GPIO_GPIO52 (GPIO_DEFAULT_CONFIG | GPIO_PIN52) +#define GPIO_MCP_ADQ2 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN52) + +#define GPIO_GPIO53 (GPIO_DEFAULT_CONFIG | GPIO_PIN53) +#define GPIO_MCP_ADQ3 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN53) + +#define GPIO_GPIO54 (GPIO_DEFAULT_CONFIG | GPIO_PIN54) +#define GPIO_MCP_ADQ4 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN54) + +#define GPIO_GPIO55 (GPIO_DEFAULT_CONFIG | GPIO_PIN55) +#define GPIO_MCP_ADQ5 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN55) + +#define GPIO_GPIO56 (GPIO_DEFAULT_CONFIG | GPIO_PIN56) +#define GPIO_MCP_ADQ6 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN56) + +#define GPIO_GPIO57 (GPIO_DEFAULT_CONFIG | GPIO_PIN57) +#define GPIO_MCP_ADQ7 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN57) + +#define GPIO_GPIO58 (GPIO_DEFAULT_CONFIG | GPIO_PIN58) +#define GPIO_MCP_ADQ8 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN58) + +#define GPIO_GPIO59 (GPIO_DEFAULT_CONFIG | GPIO_PIN59) +#define GPIO_MCP_ADQ9 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN59) + +#define GPIO_GPIO60 (GPIO_DEFAULT_CONFIG | GPIO_PIN60) +#define GPIO_MCP_ADQ10 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN60) + +#define GPIO_GPIO61 (GPIO_DEFAULT_CONFIG | GPIO_PIN61) +#define GPIO_MCP_ADQ11 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN61) + +#define GPIO_GPIO62 (GPIO_DEFAULT_CONFIG | GPIO_PIN62) +#define GPIO_MCP_ADQ12 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN62) + +#define GPIO_GPIO63 (GPIO_DEFAULT_CONFIG | GPIO_PIN63) +#define GPIO_MCP_ADQ13 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN63) + +#define GPIO_GPIO64 (GPIO_DEFAULT_CONFIG | GPIO_PIN64) +#define GPIO_MCP_ADQ14 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN64) + +#define GPIO_GPIO65 (GPIO_DEFAULT_CONFIG | GPIO_PIN65) +#define GPIO_MCP_ADQ15 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN65) + +#define GPIO_GPIO66 (GPIO_DEFAULT_CONFIG | GPIO_PIN66) +#define GPIO_MCP_ADQ16 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN66) + +#define GPIO_GPIO67 (GPIO_DEFAULT_CONFIG | GPIO_PIN67) +#define GPIO_MCP_ADQ17 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN67) + +#define GPIO_GPIO68 (GPIO_DEFAULT_CONFIG | GPIO_PIN68) +#define GPIO_MCP_ADQ18 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN68) + +#define GPIO_GPIO69 (GPIO_DEFAULT_CONFIG | GPIO_PIN69) +#define GPIO_MCP_ADQ19 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN69) + +#define GPIO_GPIO70 (GPIO_DEFAULT_CONFIG | GPIO_PIN70) +#define GPIO_MCP_ADQ20 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN70) + +#define GPIO_GPIO71 (GPIO_DEFAULT_CONFIG | GPIO_PIN71) +#define GPIO_MCP_ADQ21 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN71) + +#define GPIO_GPIO72 (GPIO_DEFAULT_CONFIG | GPIO_PIN72) +#define GPIO_MCP_ADQ22 (GPIO_ALT0 | GPIO_FLOAT | GPIO_FAST3X | GPIO_PIN72) + +#endif /* __ARCH_ARM_SRC_S5JS100_CHIP_S5JS100_PINCONFIG_H__ */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.c new file mode 100644 index 0000000000..438bf1c8df --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "s5js100_pmip.h" +#include "s5js100_pmusfr.h" +#include "s5js100_type.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ +static int pmip_fused; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +static void s5js100_pmip_trim_value(void) +{ + unsigned int pmip_option[4]; + unsigned int value, temp1, temp2, temp3, temp4, temp5, temp6; + + // read pmip option + pmip_option[0] = getreg32(0x82010504); + pmip_option[1] = getreg32(0x82010508); + pmip_option[2] = getreg32(0x8201050C); + pmip_option[3] = getreg32(0x82010510); + + if (pmip_option[0] != 0) { + pmip_fused = 1; + + /* + * Buck1 + */ + // V18TRIMB : PMIP_OPTION[11:10] + temp1 = (pmip_option[0] >> 10) & 0x3; + + // VOTRIM : PMIP_OPTION[9:7] + temp2 = (pmip_option[0] >> 7) & 0x7; + + // VSLTRIMB : PMIP_OPTION[13:12] + temp3 = (pmip_option[0] >> 12) & 0x3; + + value = (2 << 25) + (0 << 23) + (3 << 21) + (3 << 19) + (1 << 17) + (temp1 << 13) + (temp2 << 10) + (8 << 6) + (temp3 << 4) + (4 << 1); + putreg32(value, 0x81000500); + + value = (1 << 3) + (1 << 0); + putreg32(value, 0x81000504); + + /* + * Buck0 + */ + // V18TRIMB : PMIP_OPTION[4:3] + temp1 = (pmip_option[0] >> 3) & 0x3; + + // VOTRIM : PMIP_OPTION[2:0] + temp2 = (pmip_option[0] >> 0) & 0x7; + + // VSLTRIMB : PMIP_OPTION[6:5] + temp3 = (pmip_option[0] >> 6) & 0x3; + + value = (1 << 25) + (0 << 23) + (3 << 21) + (3 << 19) + (1 << 17) + (temp1 << 13) + (temp2 << 10) + (8 << 6) + (temp3 << 4) + (4 << 1); + putreg32(value, 0x82020600); + + value = (1 << 3) + (1 << 0); + putreg32(value, 0x82020604); + + /* + * BuckBoost + */ + // BTVOTM : PMIP_OPTION[28:26] + temp1 = (pmip_option[0] >> 26) & 0x7; + + // BKVOTM : PMIP_OPTION[22:20] + temp2 = (pmip_option[0] >> 20) & 0x7; + + // BBVOTM : PMIP_OPTION[25:23] + temp3 = (pmip_option[0] >> 23) & 0x7; + + // TSLTRIM : PMIP_OPTION[19:18] + temp4 = (pmip_option[0] >> 18) & 0x3; + + // KSLTRIM : PMIP_OPTION[17:16] + temp5 = (pmip_option[0] >> 16) & 0x3; + + // V18TRIM : PMIP_OPTION[15:14] + temp6 = (pmip_option[0] >> 14) & 0x3; + + value = (12 << 27) + (3 << 24) + (temp1 << 21) + (temp2 << 18) + (temp3 << 15) + (temp4 << 13) + (temp5 << 11) + (temp6 << 9) + (3 << 7) + (1 << 5) + (3 << 3) + (3 << 1); + putreg32(value, 0x85040400); + + value = (1 << 18) + (1 << 17) + (0x1c << 5) + (0x1c << 0); + putreg32(value, 0x85040404); + + /* + * LDO0 + */ + // VOTRIM : PMIP_OPTION[31:29] + temp1 = (pmip_option[0] >> 29) & 0x7; + value = (2 << 7) + (1 << 5) + (temp1 << 2) + (1 << 1); + putreg32(value, 0x81000508); + + /* + * LDO1 + */ + // VOTRIM : PMIP_OPTION[34:32] + temp1 = (pmip_option[1] >> 0) & 0x7; + value = (2 << 7) + (1 << 6) + (1 << 4) + (temp1 << 1); + putreg32(value, 0x82020608); + + /* + * LDO2 + */ + // VOTRIM : PMIP_OPTION[37:35] + temp1 = (pmip_option[1] >> 3) & 0x7; + value = (1 << 10) + (2 << 7) + (1 << 6) + (1 << 4) + (temp1 << 1); + putreg32(value, 0x8202060c); + + /* + * LDO3 + */ + // VOTRIM : PMIP_OPTION[40:38] + temp1 = (pmip_option[1] >> 6) & 0x7; + value = (2 << 7) + (2 << 4) + (temp1 << 1); + putreg32(value, 0x82020618); + + /* + * LDO4 + */ + // VOTRIM : PMIP_OPTION[43:41] + temp1 = (pmip_option[1] >> 9) & 0x7; + value = (2 << 7) + (2 << 4) + (temp1 << 1); + putreg32(value, 0x82020610); + + /* + * LDO5 + */ + // VOTRIM : PMIP_OPTION[46:44] + temp1 = (pmip_option[1] >> 12) & 0x7; + value = (2 << 7) + (1 << 4) + (temp1 << 1); + putreg32(value, 0x82020610); + + /* + * MPBGR + */ + putreg32(0x7, 0x81000510); + + /* + * DCXO LDO + */ + // VOTRIM_ANALOG : PMIP_OPTION[56:53] + // VOTRIM_DIGITAL : PMIP_OPTION[60:57] + temp1 = (pmip_option[1] >> 21) & 0x7; + temp2 = (pmip_option[1] >> 25) & 0x7; + + if (temp1 | temp2) { + value = (1 << 14) + (temp1 << 8) + (temp2 << 2) + (1 << 1) + (1 << 0); + } else { + value = (1 << 14) + (0 << 8) + (4 << 2) + (1 << 1) + (1 << 0); + } + + putreg32(value, 0x8100050c); + } +} + +/**************************************************************************** + * Name: s5js100_pmip_initialize + * + * Description: + * Initialize the PMIP. + * + * Returned Value: + * 0 : success + * <0 : fail + * + ****************************************************************************/ +int s5js100_pmip_initialize(void) +{ + // Apply pmip trim value + s5js100_pmip_trim_value(); + + // set LDO6 to 1.8V + s5js100_pmip_control_Ldo6_Tcxo(1); + + if (!pmip_fused) { + // set LDO2 to 1.2V + modifyreg32(PMU_SYS_PMIP_ANARF12_LDO, (0x1 << 10), (0x1 << 10)); + + // set MP_CTR to 0x7 + modifyreg32(PMU_ALIVE_PMIP_MPBGR_LDO, 0x3f, 0x7); + + // LDO6 + if (is_evt0()) { + putreg32((1 << 8) + (1 << 5) + (1 << 4) + (1 << 1) + (1 << 0), PMU_ALIVE_PMIP_TCXO_LDO); + } + + // DCXO LDO + putreg32((1 << 14) + (0 << 8) + (4 << 2) + (1 << 1) + (1 << 0), PMU_ALIVE_PMIP_DCXO_LDO); + } + + return 0; +} + +/**************************************************************************** + * Name: s5js100_pmip_enable_BuckBooster + * + * Description: + * control BuckBooster. 3.3V output or off + * + * Returned Value: + * a NULL on failure + * + ****************************************************************************/ +int s5js100_pmip_control_BuckBooster(int enable) +{ + if (pmip_fused) { + if (enable) { + modifyreg32(SYS_CFG_PM_BST_CFG0, 1, 1); + } else { + modifyreg32(SYS_CFG_PM_BST_CFG0, 1, 0); + } + } else { + if (enable) { + putreg32(0xE36DACB5, SYS_CFG_PM_BST_CFG0); + putreg32(0x000C738C, SYS_CFG_PM_BST_CFG1); + } else { + putreg32(0, SYS_CFG_PM_BST_CFG0); + putreg32(0, SYS_CFG_PM_BST_CFG1); + } + } + + return 1; +} + +/**************************************************************************** + * Name: s5js100_pmip_control_Ldo5_Efuse + * + * Description: + * control LDO5. 1.8V output or off + * + * Returned Value: + * a NULL on failure + * + ****************************************************************************/ +int s5js100_pmip_control_Ldo5_Efuse(int enable) +{ + if (enable) { + modifyreg32(PMU_SYS_PMIP_EFUSE18_LDO, 0x1, 0x1); + } else { + modifyreg32(PMU_SYS_PMIP_EFUSE18_LDO, 0x1, 0x0); + } + + return 1; +} + +/**************************************************************************** + * Name: s5js100_pmip_control_Ldo6_Tcxo + * + * Description: + * control TCXO LDO output or off + * + * Returned Value: + * a NULL on failure + * + ****************************************************************************/ +int s5js100_pmip_control_Ldo6_Tcxo(int enable) +{ + // VOTRIM should be set as 001b in EVT0 (1.8V) + if (is_evt0()) { + modifyreg32(PMU_ALIVE_PMIP_TCXO_LDO, (0x7 << 1), (0x1 << 1)); + } + + if (enable) { + modifyreg32(PMU_ALIVE_PMIP_TCXO_LDO, 0x80000001, 0x80000001); + } else { + modifyreg32(PMU_ALIVE_PMIP_TCXO_LDO, 0x80000001, 0x80000000); + } + + return 1; +} + +int s5js100_pmip_control_powersave(int enable) +{ + if (enable) { + /* Buck1 and LDO0 set to minimum voltage */ + modifyreg32(PMU_ALIVE_PMIP_BUCK1_CFG0, 0x7 << 10, 0); + modifyreg32(PMU_ALIVE_PMIP_DBB10_LDO, 0x7 << 2, 0); + + /* Buck0 and LDO3 set to minimum voltage */ + modifyreg32(PMU_SYS_PMIP_BUCK0_CFG0, 0x7 << 10, 0); + modifyreg32(PMU_SYS_PMIP_IO18_LDO, 0x7 << 1, 0); + } else { + s5js100_pmip_trim_value(); + } + + return 1; +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.h new file mode 100644 index 0000000000..5e4dd2d5f5 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmip.h @@ -0,0 +1,80 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_PMIP_H__ +#define __S5JS100_PMIP_H__ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#if defined(__cplusplus) +extern "C" { +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef enum { + PMIP_BUCK0, //1.35V, 1.0/1.2V LDO input + PMIP_BUCK1, //1.95V, 1.8V LDO input + PMIP_BUCKBOOST, //3.3V, PA input + PMIP_LDO0, //1.0V, Digital + PMIP_LDO1, //1.0V, Analog + PMIP_LDO2, //1.2V, Analog RF + PMIP_LDO3, //1.8V, IO + PMIP_LDO4, //1.8V, Analog RF + PMIP_LDO5, //1.8V, Efuse + PMIP_LDO6, //1.8V, TCXO + PMIP_MAX +} PMIP_PORT; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s5js100_pmip_initialize + * + * Description: + * Initialize the PMIP. + * + * Returned Value: + * a NULL on failure + * + ****************************************************************************/ +extern int s5js100_pmip_initialize(void); +extern int s5js100_pmip_control_BuckBooster(int enable); +extern int s5js100_pmip_control_Ldo5_Efuse(int enable); +extern int s5js100_pmip_control_Ldo6_Tcxo(int enable); +extern int s5js100_pmip_control_powersave(int enable); + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_S5JS100_S5JS100_PMIP_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmusfr.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmusfr.h new file mode 100644 index 0000000000..01bfc70791 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pmusfr.h @@ -0,0 +1,190 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_PMUSFR_H__ +#define __S5JS100_PMUSFR_H__ + +#define PMU_ALIVE_BASE (0x81000000) +#define PMU_SYS_BASE (0x82020000) +#define PMU_MCPU_BASE (0x84014000) +#define SYS_CFG_BASE (0x85040000) +#define BAAW_BASE (0x85010000) + +#define PMU_ALIVE_BACKUP0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0000)) +#define PMU_ALIVE_BACKUP1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0004)) +#define PMU_ALIVE_BACKUP2 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0008)) +#define PMU_ALIVE_BACKUP3 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x000c)) +#define PMU_ALIVE_SYSOFF ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x001c)) +#define PMU_ALIVE_SILENTRST ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0020)) +#define PMU_ALIVE_BOOTFLAG ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0030)) +#define PMU_ALIVE_IDSSUPPORT ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0034)) +#define PMU_ALIVE_IORET ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0038)) +#define PMU_ALIVE_TCXODCXOSEL ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x003c)) +#define PMU_ALIVE_WKUPSRCEN ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0040)) +#define PMU_ALIVE_WKUPSRCRAWSTS ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0044)) +#define PMU_ALIVE_WKUPINTSNAPSHOT ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0048)) +#define PMU_ALIVE_ALVSYSCTRLCFG ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0050)) +#define PMU_ALIVE_ALVSYSCTRL_FSMBYPASS ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0054)) +#define PMU_ALIVE_PMIPCTRL_ONTIMING ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0060)) +#define PMU_ALIVE_PMIPCTRL_OFFTIMING ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0064)) +#define PMU_ALIVE_PMIPCTRL_OVRD ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0068)) +#define PMU_ALIVE_DCXOCTRL_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0070)) +#define PMU_ALIVE_TEMPMON_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0080)) +#define PMU_ALIVE_TEMPMON_CFG1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0084)) +#define PMU_ALIVE_TEMPMON_CFG2 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0088)) +#define PMU_ALIVE_TEMPMON_CFG3 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x008c)) +#define PMU_ALIVE_TSUINT ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0090)) +#define PMU_ALIVE_SLPCLK_CFG ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00a0)) +#define PMU_ALIVE_DCXODIV_CFG ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00a4)) +#define PMU_ALIVE_RECALC_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00b0)) +#define PMU_ALIVE_RECALC_CFG1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00b4)) +#define PMU_ALIVE_RECALC_CFG2 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00b8)) +#define PMU_ALIVE_RECALC_CFG3 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00bc)) +#define PMU_ALIVE_RECALC_STS ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00c0)) +#define PMU_ALIVE_NSLEEP_CFG ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00e0)) +#define PMU_ALIVE_NSLEEP_STS0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00e4)) +#define PMU_ALIVE_NSLEEP_STS1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00e8)) +#define PMU_ALIVE_GPIOALV0CTRL ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00f0)) +#define PMU_ALIVE_GPIOALV1CTRL ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00f4)) +#define PMU_ALIVE_XTALPADCTRL ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x00f8)) +#define PMU_ALIVE_APSLPCNT_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0100)) +#define PMU_ALIVE_APSLPCNT_CFG1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0104)) +#define PMU_ALIVE_APSLPCNT_CFG2 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0108)) +#define PMU_ALIVE_APSLPCNT_CFG3 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x010c)) +#define PMU_ALIVE_APSLPCNT_CFG4 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0110)) +#define PMU_ALIVE_PROFILERCTRL ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0400)) +#define PMU_ALIVE_SYSCTRLFSM ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0404)) +#define PMU_ALIVE_DCGOVRD ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0460)) +#define PMU_ALIVE_PMIP_BUCK1_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0500)) +#define PMU_ALIVE_PMIP_BUCK1_CFG1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0504)) +#define PMU_ALIVE_PMIP_DBB10_LDO ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0508)) +#define PMU_ALIVE_PMIP_DCXO_LDO ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x050c)) +#define PMU_ALIVE_PMIP_MPBGR_LDO ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0510)) +#define PMU_ALIVE_PMIP_LP_LDO ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0514)) +#define PMU_ALIVE_PMIP_TCXO_LDO ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0518)) +#define PMU_ALIVE_DCXO_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0520)) +#define PMU_ALIVE_DCXO_CFG1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0524)) +#define PMU_ALIVE_DCXO_CFG2 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0528)) +#define PMU_ALIVE_DCXO_CFG3 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x052c)) +#define PMU_ALIVE_ROTSU_CFG0 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0530)) +#define PMU_ALIVE_ROTSU_CFG1 ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0534)) +#define PMU_ALIVE_RCO_CFG ((volatile unsigned int *)(PMU_ALIVE_BASE + 0x0540)) + +#define PMU_SYS_SYSCTRL_SYSOFF ((volatile unsigned int *)(PMU_SYS_BASE + 0x0000)) +#define PMU_SYS_ACPUCTRL_CFG0 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0010)) +#define PMU_SYS_ACPUCTRL_FSMBYPASS ((volatile unsigned int *)(PMU_SYS_BASE + 0x0014)) +#define PMU_SYS_RSTDUMPCTRL ((volatile unsigned int *)(PMU_SYS_BASE + 0x0018)) +#define PMU_SYS_RCOCOPIER ((volatile unsigned int *)(PMU_SYS_BASE + 0x0030)) +#define PMU_SYS_CMU_SYS_PMLINKDATA0 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0084)) +#define PMU_SYS_CMU_SYS_PMLINKDATA1 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0088)) +#define PMU_SYS_CMU_ACPU_PMLINKDATA0 ((volatile unsigned int *)(PMU_SYS_BASE + 0x008c)) +#define PMU_SYS_CMU_ACPU_PMLINKDATA1 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0090)) +#define PMU_SYS_CMU_MIF_PMLINKDATA0 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0094)) +#define PMU_SYS_CMU_MIF_PMLINKDATA1 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0098)) +#define PMU_SYS_LH_PSTATE ((volatile unsigned int *)(PMU_SYS_BASE + 0x0100)) +#define PMU_SYS_LH_PREQ ((volatile unsigned int *)(PMU_SYS_BASE + 0x0104)) +#define PMU_SYS_LH_PACCEPT ((volatile unsigned int *)(PMU_SYS_BASE + 0x0108)) +#define PMU_SYS_PASMASK ((volatile unsigned int *)(PMU_SYS_BASE + 0x0110)) +#define PMU_SYS_CMURST_N ((volatile unsigned int *)(PMU_SYS_BASE + 0x0114)) +#define PMU_SYS_IPRST_N ((volatile unsigned int *)(PMU_SYS_BASE + 0x0118)) +#define PMU_SYS_MCPUMON ((volatile unsigned int *)(PMU_SYS_BASE + 0x0200)) +#define PMU_SYS_PROFILERCTRL ((volatile unsigned int *)(PMU_SYS_BASE + 0x0400)) +#define PMU_SYS_ACPUCTRL_FSM ((volatile unsigned int *)(PMU_SYS_BASE + 0x0408)) +#define PMU_SYS_ACPUWORK ((volatile unsigned int *)(PMU_SYS_BASE + 0x040c)) +#define PMU_SYS_MCPUWORK ((volatile unsigned int *)(PMU_SYS_BASE + 0x0410)) +#define PMU_SYS_SPAREREG ((volatile unsigned int *)(PMU_SYS_BASE + 0x0450)) +#define PMU_SYS_DCGOVRD ((volatile unsigned int *)(PMU_SYS_BASE + 0x0460)) +#define PMU_SYS_ABX_PWRCTRL ((volatile unsigned int *)(PMU_SYS_BASE + 0x0500)) +#define PMU_SYS_DAC_PWRCTRL ((volatile unsigned int *)(PMU_SYS_BASE + 0x0520)) +#define PMU_SYS_PMIP_BUCK0_CFG0 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0600)) +#define PMU_SYS_PMIP_BUCK0_CFG1 ((volatile unsigned int *)(PMU_SYS_BASE + 0x0604)) +#define PMU_SYS_PMIP_ABB10_LDO ((volatile unsigned int *)(PMU_SYS_BASE + 0x0608)) +#define PMU_SYS_PMIP_ANARF12_LDO ((volatile unsigned int *)(PMU_SYS_BASE + 0x060c)) +#define PMU_SYS_PMIP_ANARF18_LDO ((volatile unsigned int *)(PMU_SYS_BASE + 0x0610)) +#define PMU_SYS_PMIP_EFUSE18_LDO ((volatile unsigned int *)(PMU_SYS_BASE + 0x0614)) +#define PMU_SYS_PMIP_IO18_LDO ((volatile unsigned int *)(PMU_SYS_BASE + 0x0618)) +#define PMU_SYS_SMC_LPI ((volatile unsigned int *)(PMU_SYS_BASE + 0x0700)) + +#define PMU_MCPU_LH_PSTATE ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0000)) +#define PMU_MCPU_LH_PREQ ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0004)) +#define PMU_MCPU_LH_PACCEPT ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0008)) +#define PMU_MCPU_CLKOFFREQ ((volatile unsigned int *)(PMU_MCPU_BASE + 0x000c)) +#define PMU_MCPU_PASMASK ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0020)) +#define PMU_MCPU_CMURST_N ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0030)) +#define PMU_MCPU_IPRST_N ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0034)) +#define PMU_MCPU_MDMCLKSYNC ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0040)) +#define PMU_MCPU_DCGOVRD ((volatile unsigned int *)(PMU_MCPU_BASE + 0x0050)) + +/* SYS CFG ADRESS */ +#define SYS_CFG_BAAW_ERR_LOG_AWID ((volatile unsigned int *)(SYS_CFG_BASE + 0x0000)) +#define SYS_CFG_BAAW_ERR_LOG_AWADDR ((volatile unsigned int *)(SYS_CFG_BASE + 0x0004)) +#define SYS_CFG_BAAW_ERR_LOG_ARID ((volatile unsigned int *)(SYS_CFG_BASE + 0x0008)) +#define SYS_CFG_BAAW_ERR_LOG_ARADDR ((volatile unsigned int *)(SYS_CFG_BASE + 0x000C)) +#define SYS_CFG_GNSS_MCPU2GNSS_BUS_WAKE_REQ ((volatile unsigned int *)(SYS_CFG_BASE + 0x0200)) +#define SYS_CFG_GNSS_PWRDWN_REQ ((volatile unsigned int *)(SYS_CFG_BASE + 0x0204)) +#define SYS_CFG_GNSS_BOOT_CPU_CLK_SEL ((volatile unsigned int *)(SYS_CFG_BASE + 0x0208)) +#define SYS_CFG_GNSS_AVAIL ((volatile unsigned int *)(SYS_CFG_BASE + 0x020C)) +#define SYS_CFG_PM_BST_CFG0 ((volatile unsigned int *)(SYS_CFG_BASE + 0x0400)) +#define SYS_CFG_PM_BST_CFG1 ((volatile unsigned int *)(SYS_CFG_BASE + 0x0404)) +#define SYS_CFG_CHIP_VER ((volatile unsigned int *)(SYS_CFG_BASE + 0x1000)) +#define SYS_CFG_LH_RCG_EN ((volatile unsigned int *)(SYS_CFG_BASE + 0x1010)) +#define SYS_CFG_PAS ((volatile unsigned int *)(SYS_CFG_BASE + 0x1014)) +#define SYS_CFG_PPMU ((volatile unsigned int *)(SYS_CFG_BASE + 0x1018)) +#define SYS_CFG_CELLULAR_GNSS_SEL ((volatile unsigned int *)(SYS_CFG_BASE + 0x101C)) +#define SYS_CFG_UARTWCI_SEL ((volatile unsigned int *)(SYS_CFG_BASE + 0x1020)) +#define SYS_CFG_CFG_SSS_EXT_ACCESS ((volatile unsigned int *)(SYS_CFG_BASE + 0x102C)) +#define SYS_CFG_USI0_SW_CONF ((volatile unsigned int *)(SYS_CFG_BASE + 0x1030)) +#define SYS_CFG_USI0_IPCLK ((volatile unsigned int *)(SYS_CFG_BASE + 0x1034)) +#define SYS_CFG_USI1_SW_CONF ((volatile unsigned int *)(SYS_CFG_BASE + 0x1038)) +#define SYS_CFG_USI1_IPCLK ((volatile unsigned int *)(SYS_CFG_BASE + 0x103C)) +#define SYS_CFG_MCPU_HALTN ((volatile unsigned int *)(SYS_CFG_BASE + 0x1040)) +#define SYS_CFG_CM7_HALTED_MASK ((volatile unsigned int *)(SYS_CFG_BASE + 0x1044)) +#define SYS_CFG_CM0_HALTED ((volatile unsigned int *)(SYS_CFG_BASE + 0x1048)) +#define SYS_CFG_CM0_HRESETN_CTL ((volatile unsigned int *)(SYS_CFG_BASE + 0x104C)) +#define SYS_CFG_SRAM_RA1_HS ((volatile unsigned int *)(SYS_CFG_BASE + 0x1050)) +#define SYS_CFG_SRAM_RF1_HS ((volatile unsigned int *)(SYS_CFG_BASE + 0x1054)) +#define SYS_CFG_SRAM_RA1_HD ((volatile unsigned int *)(SYS_CFG_BASE + 0x1060)) +#define SYS_CFG_SRAM_RF1_HD ((volatile unsigned int *)(SYS_CFG_BASE + 0x1064)) +#define SYS_CFG_SRAM_RF2_HD ((volatile unsigned int *)(SYS_CFG_BASE + 0x1068)) +#define SYS_CFG_VROM_HD ((volatile unsigned int *)(SYS_CFG_BASE + 0x106C)) +#define SYS_CFG_RXADC_RCCAL0 ((volatile unsigned int *)(SYS_CFG_BASE + 0x1200)) +#define SYS_CFG_RXADC_RCCAL1 ((volatile unsigned int *)(SYS_CFG_BASE + 0x1204)) +#define SYS_CFG_RXADC_RCCAL2 ((volatile unsigned int *)(SYS_CFG_BASE + 0x1208)) +#define SYS_CFG_RXADC_RCCAL3 ((volatile unsigned int *)(SYS_CFG_BASE + 0x120C)) +#define SYS_CFG_BLK_CTRL ((volatile unsigned int *)(SYS_CFG_BASE + 0x1800)) + +/* BAAW ADRESS */ +#define BAAW_SRC_START_ADDR_0 ((volatile unsigned int *)(BAAW_BASE + 0x0000)) +#define BAAW_SRC_END_ADDR_0 ((volatile unsigned int *)(BAAW_BASE + 0x0004)) +#define BAAW_REMAPPED_ADDR_0 ((volatile unsigned int *)(BAAW_BASE + 0x0008)) +#define BAAW_ACCESS_ENABLE_OF_WINDOW_0 ((volatile unsigned int *)(BAAW_BASE + 0x000c)) +#define BAAW_SRC_START_ADDR_1 ((volatile unsigned int *)(BAAW_BASE + 0x0010)) +#define BAAW_SRC_END_ADDR_1 ((volatile unsigned int *)(BAAW_BASE + 0x0014)) +#define BAAW_REMAPPED_ADDR_1 ((volatile unsigned int *)(BAAW_BASE + 0x0018)) +#define BAAW_ACCESS_ENABLE_OF_WINDOW_1 ((volatile unsigned int *)(BAAW_BASE + 0x001c)) +#define BAAW_SRC_START_ADDR_2 ((volatile unsigned int *)(BAAW_BASE + 0x0020)) +#define BAAW_SRC_END_ADDR_2 ((volatile unsigned int *)(BAAW_BASE + 0x0024)) +#define BAAW_REMAPPED_ADDR_2 ((volatile unsigned int *)(BAAW_BASE + 0x0028)) +#define BAAW_ACCESS_ENABLE_OF_WINDOW_2 ((volatile unsigned int *)(BAAW_BASE + 0x002C)) +#define BAAW_SRC_START_ADDR_3 ((volatile unsigned int *)(BAAW_BASE + 0x0030)) +#define BAAW_SRC_END_ADDR_3 ((volatile unsigned int *)(BAAW_BASE + 0x0034)) +#define BAAW_REMAPPED_ADDR_3 ((volatile unsigned int *)(BAAW_BASE + 0x0038)) +#define BAAW_ACCESS_ENABLE_OF_WINDOW_3 ((volatile unsigned int *)(BAAW_BASE + 0x003C)) + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.c new file mode 100644 index 0000000000..d6d75522ab --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.c @@ -0,0 +1,1151 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include "cmsis_os.h" +#include "s5js100.h" +#include "s5js100_type.h" +#include "s5js100_pwr.h" +#include "s5js100_pmusfr.h" +#include "s5js100_pmip.h" +#include "s5js100_cmu.h" + +#include "mbed_trace.h" +#include "platform/mbed_wait_api.h" +#include "platform/mbed_thread.h" +#define TRACE_GROUP "PWR" + +#ifndef S5JS100_PWR_DBG_ON +#define S5JS100_PWR_DBG_ON 0 +#endif +#define S5JS100_PWR_DBG if (S5JS100_PWR_DBG_ON) tr_info + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#define OFF 0 +#define ON 1 + +/**************************************************************************** + * Private Data + ****************************************************************************/ +enum _PMU_CMD_ { + PMU_CMD_RESET = 1, + PMU_CMD_INIT, + PMU_CMD_SLEEP, + PMU_CMD_AUTO, + PMU_CMD_SHORTSLEEP, +}; + +static PORT_NUM alv_wkup_src; +static FILTER_TYPE wkup_type; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static void hw_delay_us(unsigned int Value) +{ + volatile unsigned i, j; + + for (i = 0; i < (Value * 2); i++) + for (j = 0; j < 100; j++); +} + +#ifdef PRINT_NBSLEEP_LOG +static void direct_uart(char *buf, unsigned int buf_len) +{ +#if 0 + unsigned int i; + for (i = 0; i < buf_len; i++) { + up_putc(buf[i]); + } +#endif +} + +static void convert2hex(char *_buffer, unsigned int data) +{ + // we make our string assuming all hex digits are 0 to 9 + // string will be of the form 0xabcd + // where a,b,c,d are the individual hex digits + _buffer[0] = '0'; + _buffer[1] = 'x'; + _buffer[2] = ((data >> 28) & 0x0F) + '0'; + _buffer[3] = ((data >> 24) & 0x0F) + '0'; + _buffer[4] = ((data >> 20) & 0x0F) + '0'; + _buffer[5] = ((data >> 16) & 0x0F) + '0'; + _buffer[6] = ((data >> 12) & 0x0F) + '0'; + _buffer[7] = ((data >> 8) & 0x0F) + '0'; + _buffer[8] = ((data >> 4) & 0x0F) + '0'; + _buffer[9] = ((data) & 0x0F) + '0'; + _buffer[10] = '\n'; + + // now we correct for the case where a digit + // is A to F: + if (_buffer[2] > '9') { + _buffer[2] += 7; + } + if (_buffer[3] > '9') { + _buffer[3] += 7; + } + if (_buffer[4] > '9') { + _buffer[4] += 7; + } + if (_buffer[5] > '9') { + _buffer[5] += 7; + } + if (_buffer[6] > '9') { + _buffer[6] += 7; + } + if (_buffer[7] > '9') { + _buffer[7] += 7; + } + if (_buffer[8] > '9') { + _buffer[8] += 7; + } + if (_buffer[9] > '9') { + _buffer[9] += 7; + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +extern char *get_env(const char *name); +extern int s5js100_dcxo_initialize(void); +MCPU_MODE mcpu_device_mode = MCPU_NONE; + +void pmu_sys_cdc_clk_en(int poweron) +{ + modifyreg32(PMU_SYS_DCGOVRD, 1 << 1, poweron << 1); +} + +void pmu_alive_cdc_clk_en(int poweron) +{ + modifyreg32(PMU_ALIVE_DCGOVRD, 1 << 1, poweron << 1); +} + +void mcpu_bin_loading(unsigned int tcm_base_addr, unsigned int flash_base_addr, unsigned int size) +{ + memcpy((void *)tcm_base_addr, (void *)flash_base_addr, size); + + /* Select one cache invaildate function from below */ + SCB_CleanInvalidateDCache_by_Addr((void *)tcm_base_addr, size); + //SCB_CleanInvalidateDCache(); +} + +unsigned int get_pmu_sys_mcpu_core_status(void) +{ + return getreg32(PMU_SYS_MCPUMON); +} + +void pmu_sys_asyncbus_mask(PWR_BLK eblock) +{ + unsigned int val; + val = getreg32(PMU_SYS_PASMASK); + putreg32(val & (~eblock), PMU_SYS_PASMASK); +} + +void pmu_sys_asyncbus_unmask(PWR_BLK eblock) +{ + modifyreg32(PMU_SYS_PASMASK, 0x3, eblock); +} + +void pmu_sys_reset(PWR_BLK eblock, int reset) +{ + if (reset == 1) { + putreg32(getreg32(PMU_SYS_IPRST_N) & (~eblock), PMU_SYS_IPRST_N); + putreg32(getreg32(PMU_SYS_CMURST_N) & (~eblock), PMU_SYS_CMURST_N); + } else { + modifyreg32(PMU_SYS_CMURST_N, 0x3, eblock); + hw_delay_us(1); + modifyreg32(PMU_SYS_IPRST_N, 0x3, eblock); + hw_delay_us(1); + } +} + +unsigned int get_temp(void) +{ + unsigned int i, CurTemp = 0; + + putreg32(0x201f2, PMU_ALIVE_ROTSU_CFG1); + putreg32((1u << 29) + (1u << 28), PMU_ALIVE_ROTSU_CFG0); + + for (i = 0; i < 10; i++) { + putreg32((1u << 29) + (1u << 28) + (1u << 24), PMU_ALIVE_ROTSU_CFG0); + hw_delay_us(120); + putreg32((1u << 29) + (1u << 28) + (0u << 24), PMU_ALIVE_ROTSU_CFG0); + hw_delay_us(10); + CurTemp += getreg32(PMU_ALIVE_ROTSU_CFG0) & 0x7ff; + putreg32(0, PMU_ALIVE_ROTSU_CFG0); + } + + return CurTemp / 10; +} + +unsigned int get_rotsu_value(int count) +{ + int i, value = 0; + + putreg32(0x201f2, PMU_ALIVE_ROTSU_CFG1); + putreg32((1u << 29) + (1u << 28), PMU_ALIVE_ROTSU_CFG0); + + for (i = 0; i < count; i++) { + putreg32((1u << 29) + (1u << 28) + (1u << 24), PMU_ALIVE_ROTSU_CFG0); + hw_delay_us(120); + putreg32((1u << 29) + (1u << 28) + (0u << 24), PMU_ALIVE_ROTSU_CFG0); + hw_delay_us(10); + value += getreg32(PMU_ALIVE_ROTSU_CFG0) & 0x7ff; + putreg32(0, PMU_ALIVE_ROTSU_CFG0); + } + + return value; +} + +int rotsu_get_temperature(void) +{ + int adc, celcius; + + adc = get_rotsu_value(10); + celcius = ((100 * adc - 683040) * 100) / 680; + + return (celcius + 50000); +} + +bool mcpu_is_on(void) +{ + if (getreg32(SYS_CFG_MCPU_HALTN) == 0x0) { + return false; + } else { + return true; + } +} + +void mcpu_reset(void) +{ + mcpu_device_mode = MCPU_NONE; + + /* if off, do nothing */ + if (getreg32(SYS_CFG_MCPU_HALTN) == 0x0) { + return; + } + + putreg32(0x0, SYS_CFG_MCPU_HALTN); + + pmu_sys_cdc_clk_en(ON); + + putreg32(0x0, PMU_SYS_LH_PSTATE); + putreg32(0xf, PMU_SYS_LH_PREQ); + while (getreg32(PMU_SYS_LH_PACCEPT) != 0xF); + putreg32(0x0, PMU_SYS_LH_PREQ); + while (getreg32(PMU_SYS_LH_PACCEPT) != 0x0); + + pmu_sys_asyncbus_mask(RFIP_BLK + MCPU_BLK); + pmu_sys_reset(RFIP_BLK + MCPU_BLK, 1); + + pmu_sys_cdc_clk_en(OFF); + +} + +void s5js100_pmu_init(void); +void mcpu_init(MCPU_MODE device) +{ + mcpu_reset(); + + s5js100_pmu_init(); + + putreg32(0x1, SYS_CFG_LH_RCG_EN); + putreg32(0x2, SYS_CFG_PPMU); + putreg32(0x0, SYS_CFG_PAS); + + putreg32(0x40000, BAAW_SRC_START_ADDR_0); + putreg32(0x41000, BAAW_SRC_END_ADDR_0); + putreg32(0x40000, BAAW_REMAPPED_ADDR_0); + putreg32(0x80000003, BAAW_ACCESS_ENABLE_OF_WINDOW_0); + + putreg32(0x10000, BAAW_SRC_START_ADDR_1); + putreg32(0x10010, BAAW_SRC_END_ADDR_1); + putreg32(0x10000, BAAW_REMAPPED_ADDR_1); + putreg32(0x80000003, BAAW_ACCESS_ENABLE_OF_WINDOW_1); + + putreg32(0x85022, BAAW_SRC_START_ADDR_2); + putreg32(0x85042, BAAW_SRC_END_ADDR_2); + putreg32(0x85022, BAAW_REMAPPED_ADDR_2); + putreg32(0x80000003, BAAW_ACCESS_ENABLE_OF_WINDOW_2); + + putreg32(0x82021, BAAW_SRC_START_ADDR_3); + putreg32(0x82022, BAAW_SRC_END_ADDR_3); + putreg32(0x85022, BAAW_REMAPPED_ADDR_3); + putreg32(0x80000003, BAAW_ACCESS_ENABLE_OF_WINDOW_3); + + mcpu_bin_loading(TCM_BASE, (device == MCPU_CP) ? CP_BIN_BASE : GNSS_BIN_BASE, MCPU_BINARY_SIZE); + + switch (device) { + case MCPU_CP: + putreg32(0x01000001, 0x82000A04); //SCMU_MR_REGISTER_A04 + putreg32(0x0, SYS_CFG_CELLULAR_GNSS_SEL); + putreg32(0x1, PMU_SYS_ABX_PWRCTRL); + break; + case MCPU_GNSS: + putreg32(0x01020001, 0x82000A04); //SCMU_MR_REGISTER_A04 + putreg32(0x1, SYS_CFG_CELLULAR_GNSS_SEL); + putreg32(0xe7, PMU_SYS_ABX_PWRCTRL); + break; + default: +#if defined (__ARMCC_VERSION) + while (1); +#else + asm("b ."); +#endif + break; + } + + + /* DEVICE DEPENDENT CODE!!! WRONG PALCE!!! + Move it in Users application or device init section. + // 4. Pin mux chagen for RF signal + modifyreg32(0x8202110c, 0x7, 0x2); //XGPIO3, when 0x2, PA_MODE0 is selected. + modifyreg32(0x82021110, 0x7, 0x2); //XGPIO4, when 0x2, PA_MODE1 is selected. + modifyreg32(0x82021114, 0x7, 0x2); //XGPIO5, when 0x2, PA_ON0 is selected. + modifyreg32(0x82021118, 0x7, 0x2); //XGPIO6, when 0x2, PA_ON1 is selected.. + */ + // 5. Buck boost turn on. + s5js100_pmip_control_BuckBooster(1); + + // 6. mcpu run + putreg32(0x1, SYS_CFG_MCPU_HALTN); // PAS_ICG_DIS=0, PAS_PREQ_QUICK_STARTn=0 + + S5JS100_PWR_DBG("\nMCPU BOOT\n"); + + if (device == MCPU_GNSS) { + //printf("\nSetting FOR GNSS\n"); + putreg32(0x7004, 0x8202114C); + putreg32(0x7004, 0x82021150); + putreg32(0x7004, 0x82021154); + putreg32(0x7004, 0x82021158); + putreg32(0x7004, 0x8202115C); + + S5JS100_PWR_DBG("\nXANT_SW change\n"); + putreg32(0x4107, 0x82021088); + putreg32(0x4107, 0x8202108C); + putreg32(0x4107, 0x82021090); + + S5JS100_PWR_DBG("\nGPIO Out enable\n"); + putreg32(0x00001000, 0x85026104); + putreg32(0xFFFFc7FF, 0x85026004); + putreg32(0x6303, 0x8202111c); + putreg32(0x100, 0x820009e0); + + } else { + S5JS100_PWR_DBG("\nSetting FOR CP\n"); + + putreg32(0x0, 0x8504101C); + putreg32(0x0, 0x8504120C); + putreg32(0x8, 0x8504120C); + putreg32(0xf9f4f44, 0x85041208); + putreg32(0xC, 0x8504120C); + + /* check if eFUSE ABX value available */ + if (getreg32(0x82010500) != 0x0) { + S5JS100_PWR_DBG("ABX CAL, with EFUSE..(0x%x)\n", getreg32(0x82010500)); + putreg32(getreg32(0x82010500) & 0x3FF, 0x85041204); + putreg32(0x09, 0x8504120C); + S5JS100_PWR_DBG("0x8504120C=0x%x\n", getreg32(0x8504120C)); + S5JS100_PWR_DBG("ABX value : 0x%8X\n", getreg32(0x85041204)); + S5JS100_PWR_DBG("0x85041200 value : 0x%8X\n", getreg32(0x85041200)); + S5JS100_PWR_DBG("0x85041204 value : 0x%8X\n", getreg32(0x85041204)); + S5JS100_PWR_DBG("0x85041208 value : 0x%8X\n", getreg32(0x85041208)); + S5JS100_PWR_DBG("0x8504120C value : 0x%8X\n", getreg32(0x8504120C)); + } else { + S5JS100_PWR_DBG("ABX AUTO CAL\n"); + S5JS100_PWR_DBG("Check 1st register\n"); + S5JS100_PWR_DBG("0x85041200 value : 0x%8X\n", getreg32(0x85041200)); + S5JS100_PWR_DBG("0x85041204 value : 0x%8X\n", getreg32(0x85041204)); + S5JS100_PWR_DBG("0x85041208 value : 0x%8X\n", getreg32(0x85041208)); + S5JS100_PWR_DBG("0x8504120C value : 0x%8X\n", getreg32(0x8504120C)); + + putreg32(getreg32(0x85041204) | (1 << 10), 0x85041204); + putreg32(getreg32(0x8504120C) | (1 << 2), 0x8504120C); + //while (!(getreg32(0x85041200) & (1 << 10))); + //wait_ms(10); + thread_sleep_for(10); + putreg32(getreg32(0x85041200) & 0x3FF, 0x85041204); + if ((getreg32(0x85041204) & 0x3FF) == 0x0) { + putreg32(0x210, 0x85041204); + } + S5JS100_PWR_DBG("Check 2nd register\n"); + S5JS100_PWR_DBG("ABX value : 0x%8X\n", getreg32(0x85041204)); + S5JS100_PWR_DBG("0x85041200 value : 0x%8X\n", getreg32(0x85041200)); + S5JS100_PWR_DBG("0x85041204 value : 0x%8X\n", getreg32(0x85041204)); + S5JS100_PWR_DBG("0x85041208 value : 0x%8X\n", getreg32(0x85041208)); + S5JS100_PWR_DBG("0x8504120C value : 0x%8X\n", getreg32(0x8504120C)); + } + + S5JS100_PWR_DBG("ABX CAL, DAC..\n"); + putreg32(0x0D, 0x8504120C); + + + S5JS100_PWR_DBG("r_USIM0_DATA pull up enable..\n"); + modifyreg32(0x82021040, (0x3 << 11), (0x3 << 11)); + } + + modifyreg32(PMU_SYS_ABX_PWRCTRL, 0x1, 0x0); + + if (device == MCPU_CP) { + S5JS100_PWR_DBG("PMU DAC PWR control..\n"); + modifyreg32(PMU_SYS_DAC_PWRCTRL, 0x1, 0x0); + S5JS100_PWR_DBG("NSLEEP Enable / don't update re-calculated counter value..\n"); + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, (0x7 << 7), (0x7 << 7)); + putreg32((1u << 2) + (1u << 0) + (1u << 1), PMU_ALIVE_NSLEEP_CFG); // [0] :wakeup interrupt enable , [1]: sys_valid_int_en + S5JS100_PWR_DBG("CP boot done..\n"); + + } + + mcpu_device_mode = device; +} + + +void s5js100_sw_powerdomain_off(PWR_BLK eblock) +{ + pmu_sys_cdc_clk_en(ON); + + if (eblock & MCPU_BLK) { + modifyreg32(PMU_SYS_ABX_PWRCTRL, 0x1, 0x1); + modifyreg32(PMU_SYS_DAC_PWRCTRL, 0x1, 0x1); + + if (getreg32(PMU_SYS_IPRST_N)) { + putreg32(0x0, PMU_SYS_LH_PSTATE); + putreg32(0xf, PMU_SYS_LH_PREQ); + while (getreg32(PMU_SYS_LH_PACCEPT) != 0xF); + putreg32(0x0, PMU_SYS_LH_PREQ); + while (getreg32(PMU_SYS_LH_PACCEPT) != 0x0) ; + } + } + + hw_delay_us(1); + pmu_sys_asyncbus_mask(eblock); + pmu_sys_reset(eblock, 1); + pmu_sys_cdc_clk_en(OFF); + +} + +void s5js100_sw_powerdomain_on(PWR_BLK eblock) +{ + pmu_sys_cdc_clk_en(ON); + + pmu_sys_asyncbus_unmask(eblock); + pmu_sys_reset(eblock, 0); + + if (eblock & MCPU_BLK) { + putreg32(0xf, PMU_SYS_LH_PSTATE); + putreg32(0xf, PMU_SYS_LH_PREQ); + while (getreg32(PMU_SYS_LH_PACCEPT) != 0xF); + putreg32(0x0, PMU_SYS_LH_PREQ); + while (getreg32(PMU_SYS_LH_PACCEPT) != 0x0) ; + } + + pmu_sys_cdc_clk_en(OFF); +} + +unsigned int get_bootflag(void) +{ + return !!(getreg32(PMU_ALIVE_BOOTFLAG) & 1); +} + +void alive_gpio_cfg(PORT_NUM gpio, PORT_DIR cfg) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio, (0x3 << 0), 1 << cfg); +} + +void alive_gpio_set_value(PORT_NUM gpio, int value) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio, (0x1 << 5), value << 5); +} + +int alive_gpio_get_value(PORT_NUM gpio) +{ + return ((getreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio) >> 4) & 0x1); +} + +void gpio_set_pull(PORT_NUM gpio, PUD_CON mode) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio, (0x3 << 2), mode << 2); +} + +void gpio_eint_mask(PORT_NUM gpio) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio, (1u << 9), 0x0 << 9); +} + +void gpio_eint_unmask(PORT_NUM gpio) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio, (1u << 9), 0x1 << 9); +} + +int gpio_eint_is_pending(PORT_NUM gpio) +{ + return ((getreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + gpio * 0x4) >> 10) & 0x1); +} + +void gpio_eint_clear_pending(PORT_NUM gpio) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + gpio * 0x4, (1u << 10), 1 << 10); +} + +void gpio_eint_set_filter(PORT_NUM gpio, FILTER_TYPE type) +{ + modifyreg32((uint32_t)PMU_ALIVE_GPIOALV0CTRL + 0x4 * gpio, (0x3 << 6), type << 6); +} + +void sel_recalculate_clk(void) +{ + if (getreg32(PMU_ALIVE_TCXODCXOSEL) == 0x2) { + /* keep TCXO clk source */ + modifyreg32(PMU_ALIVE_TCXODCXOSEL, (0x1 << 0), 1); + } else { + /* keep DCXO clk source */ + } + +} + +bool is_TCXO(void) +{ + if (getreg32(PMU_ALIVE_TCXODCXOSEL) & (0x1 << 1)) { + return 1; + } else { + return 0; + } +} + + + +extern int external_pin; +static int alvgpio_interrupt(void) +{ + if (!strcmp(get_env("ALVTOGGLE"), "ON")) { + + external_pin = !external_pin; + + } else { + //putreg8( '>' , 0x83014020); + //putreg8( (external_pin&0xFF) + 0x30, 0x83014020); + if (!((getreg32(0x810000f0 + alv_wkup_src * 0x4) & (1 << 4)) >> 4 ^ wkup_type)) { + gpio_eint_set_filter(alv_wkup_src, !wkup_type); + external_pin = 1; + } else { + gpio_eint_set_filter(alv_wkup_src, wkup_type); + external_pin = 0; + } + //putreg8( (external_pin&0xFF) + 0x30, 0x83014020); + //putreg8( '<' , 0x83014020); + //putreg8( '\r' , 0x83014020); + //putreg8( '\n' , 0x83014020); + } + gpio_eint_clear_pending(alv_wkup_src); + putreg32(0x4, 0xE000E280); + return 0; +} + +void alvgpio_interrupt_enable(void) +{ + if (alv_wkup_src != GPIO_ALIVE_NONE) { + NVIC_SetVector(S5JS100_IRQ_PMU_AlivePad, (unsigned int)alvgpio_interrupt); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + gpio_eint_unmask(alv_wkup_src); + NVIC_EnableIRQ(S5JS100_IRQ_PMU_AlivePad); + } +} + +#define GPIO_ALIVE_CTRL(x) (0x810000f0 + (x) * 0x4) +void alvgpio_init(void) +{ + int toggle = 0; + putreg32(0x0, GPIO_ALIVE_CTRL(0)); + putreg32(0x0, GPIO_ALIVE_CTRL(1)); + + // Set GPIOx to be input pull down + modifyreg32(GPIO_ALIVE_CTRL(0), (0x1 << 0x2), (0x1 << 0x2)); //Pullup/down enable + modifyreg32(GPIO_ALIVE_CTRL(0), (0x1 << 0x3), (0x0 << 0x3)); //Input pull-down + + modifyreg32(GPIO_ALIVE_CTRL(1), (0x1 << 0x2), (0x1 << 0x2)); //Pullup/down enable + modifyreg32(GPIO_ALIVE_CTRL(1), (0x1 << 0x3), (0x0 << 0x3)); //Input pull-down + + + + modifyreg32(0x85023088, 0x1, 0x1); + + // select wakeup source + alv_wkup_src = GPIO_ALIVE_NONE; + + if (!strcmp(get_env("ALVTOGGLE"), "ON")) { + toggle = 1; + wkup_type = RISING; + } else { + wkup_type = HIGHLEVEL; + } + + if (!strncmp(get_env("WAKEUP"), "ALVGPIO0", 8)) { + alv_wkup_src = GPIO_ALIVE_0; + } + if (!strncmp(get_env("WAKEUP"), "ALVGPIO1", 8)) { + alv_wkup_src = GPIO_ALIVE_1; + } + + // GpioAlv Output enable + if (!strcmp(get_env("ALVGPIO0"), "HIGH")) { + modifyreg32(GPIO_ALIVE_CTRL(0), 0x21, 0x21); + } + if (!strcmp(get_env("ALVGPIO0"), "LOW")) { + modifyreg32(GPIO_ALIVE_CTRL(0), 0xC, 0x4); + } + if (!strcmp(get_env("ALVGPIO1"), "HIGH")) { + modifyreg32(GPIO_ALIVE_CTRL(1), 0x21, 0x21); + } + if (!strcmp(get_env("ALVGPIO1"), "LOW")) { + modifyreg32(GPIO_ALIVE_CTRL(1), 0xC, 0x4); + } + + if (alv_wkup_src != GPIO_ALIVE_NONE) { + + // wkup src trigger + if (get_env("WAKEUP")[8] == 'H') { + wkup_type = toggle ? RISING : HIGHLEVEL; + } + if (get_env("WAKEUP")[8] == 'L') { + wkup_type = toggle ? FALLING : LOWLEVEL; + } + + // wkup src Input enable + modifyreg32(GPIO_ALIVE_CTRL(alv_wkup_src), 0x2, 0x2); + + if (toggle) { + gpio_eint_set_filter(alv_wkup_src, wkup_type); + } else { + if (!((getreg32(0x810000f0 + alv_wkup_src * 0x4) & (1 << 4)) >> 4 ^ wkup_type)) { + gpio_eint_set_filter(alv_wkup_src, !wkup_type); + external_pin = 1; + } else { + gpio_eint_set_filter(alv_wkup_src, wkup_type); + external_pin = 0; + } + } + } + + // interrupt clear at PMU_ALIVE + gpio_eint_clear_pending(GPIO_ALIVE_0); + gpio_eint_clear_pending(GPIO_ALIVE_1); + + // pending clear AlivePadInt + putreg32(0x4, 0xE000E280); +} + +void s5js100_pmu_init(void) +{ + unsigned int pmu_alive_slpclk_cfg = 1; + +#if USE_SLOW_CLOCK_TCXO + pmu_alive_slpclk_cfg = 0; +#else + if (!strncmp(get_env("BOARD"), "0.2", 3)) { + pmu_alive_slpclk_cfg = 0; + } +#endif + + alvgpio_init(); + alvgpio_interrupt_enable(); + + if (get_bootflag() == COLD_BOOT) { + putreg32(pmu_alive_slpclk_cfg, PMU_ALIVE_SLPCLK_CFG); + + putreg32((1u << 0) + (3u << 4) + (3u << 8) + (3u << 12) + (4u << 16) + (5u << 20) + (5u << 24) + (6u << 28), PMU_ALIVE_PMIPCTRL_ONTIMING); + putreg32((1u << 0) + (1u << 4) + (1u << 8), PMU_ALIVE_PMIPCTRL_OFFTIMING); + putreg32((4u << 10) + (4u << 6), PMU_ALIVE_DCXOCTRL_CFG0); + + sel_recalculate_clk(); + + putreg32(0x001, PMU_ALIVE_RECALC_CFG2); + putreg32((1u << 31) + (2u << 0), PMU_ALIVE_RECALC_CFG3); + } else { + putreg32(0x0, PMU_ALIVE_SYSOFF); + + putreg32(pmu_alive_slpclk_cfg, PMU_ALIVE_SLPCLK_CFG); + + if ((getreg32(PMU_ALIVE_WKUPINTSNAPSHOT) & GPIO_ALV0) > 0) { + //putreg32((1u << 10), PMU_ALIVE_GPIOALV0CTRL); + //putreg32((1u << 2) + (1u << 1), PMU_ALIVE_GPIOALV0CTRL); + } + if ((getreg32(PMU_ALIVE_WKUPINTSNAPSHOT) & GPIO_ALV1) > 0) { + //putreg32((1u << 10), PMU_ALIVE_GPIOALV1CTRL); + //putreg32((1u << 3) + (1u << 2) + (1u << 1), PMU_ALIVE_GPIOALV1CTRL); + } + if ((getreg32(PMU_ALIVE_WKUPINTSNAPSHOT) & APSLPCNT) > 0) { + modifyreg32(PMU_ALIVE_APSLPCNT_CFG0, (1u << 3), 0 << 3); + putreg32(0, PMU_ALIVE_APSLPCNT_CFG0); + } + if ((getreg32(PMU_ALIVE_WKUPINTSNAPSHOT) & NSLEEP) > 0) { + //do what? + } + if ((getreg32(PMU_ALIVE_WKUPINTSNAPSHOT) & TEMPMON) > 0) { + modifyreg32(PMU_ALIVE_TSUINT, (1u << 3), 1 << 3); + } + } + + putreg32(0xf21, PMU_ALIVE_PMIPCTRL_OFFTIMING); + s5js100_sw_powerdomain_on(MCPU_BLK + RFIP_BLK); + putreg32(0x0, PMU_SYS_PROFILERCTRL); + putreg32((1u << 2), PMU_SYS_PROFILERCTRL); + + s5js100_pmip_initialize(); + + s5js100_dcxo_initialize(); + +} + + +//#define SLPCLK 0.031941f // MHz ..26/DCXO(814) +//#define SLPCLK_DIV 814 // MHz ..26/DCXO(814) + +#define SLPCLK 0.032786f // MHz ..26/DCXO(793) +#define SLPCLK_DIV 793 // MHz ..26/DCXO(793) + +void set_sleep_counter(unsigned int time_ms) +{ + unsigned int count; + count = (unsigned int)(time_ms * SLPCLK * 1000); + + putreg32(count >> 20, PMU_ALIVE_APSLPCNT_CFG1); + putreg32(count & 0xfffff, PMU_ALIVE_APSLPCNT_CFG2); +} + +void conver_nbsleep_to_aspsleep_counter(unsigned int nbsleep_cnt) +{ + putreg32(nbsleep_cnt >> 20, PMU_ALIVE_APSLPCNT_CFG1); + putreg32(nbsleep_cnt & 0xfffff, PMU_ALIVE_APSLPCNT_CFG2); +} + + +void enable_counter(void) +{ + if (getreg32(PMU_ALIVE_APSLPCNT_CFG0) & (0x1 << 1)) { + //lldbg("APSLP cnt already enabled\n"); + } else { + putreg32(0, PMU_ALIVE_APSLPCNT_CFG1); + putreg32(1, PMU_ALIVE_APSLPCNT_CFG2); + putreg32(0x3, PMU_ALIVE_APSLPCNT_CFG0); + putreg32((15u << 6) + (1u << 3) + (0u << 2) + (1u << 1) + (1u << 0), PMU_ALIVE_APSLPCNT_CFG0); + } +} +void disable_counter(void) +{ + putreg32(0x3, PMU_ALIVE_APSLPCNT_CFG0); +} +long long get_counter(void) +{ + long long current_count = 0; + current_count = getreg32(PMU_ALIVE_APSLPCNT_CFG3) << 20; + current_count |= getreg32(PMU_ALIVE_APSLPCNT_CFG4); + S5JS100_PWR_DBG("H_COUNT : 0x%x ,L_COUNT : 0x%x ,\n", (unsigned int)(0xffff & (current_count >> 20)), (unsigned int)(0xfffff & current_count)); + return current_count; +} + +void s5js100_pmu_sleep(PMU_SLEEP_INFO *info) +{ + PMU_SLEEP_INFO *pmu_info = (PMU_SLEEP_INFO *)((uintptr_t) info); + unsigned int cur_temp; + unsigned int _wkupsrc = pmu_info->wakeup_src; + + putreg32(0x0, 0xe000e010); //disable tick , not to interrupt in wfi state + putreg32(0x02000000, 0xe000ed04); //Pend SysTick clear + putreg32(0xFFFFFFFF, 0xe000e180); //IRQ0_31 disable + putreg32(0xFFFFFFFF, 0xe000e184); //IRQ32_64 disable + putreg32(0xFFFFFFFF, 0xe000e280); //IRQ0_31_PEN clear + putreg32(0xFFFFFFFF, 0xe000e284); //IRQ32_64_PEN clear + + putreg32(0, PMU_ALIVE_SLPCLK_CFG); //SwMuxSel=0 1: SwSel selects sleep clock mux + + //disable SMC clockgating + putreg32(0x200000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SMC_IPCLKPORT_CLK); + putreg32(0x200000, MIFCMU_CLK_CON_GAT_GOUT_MIF_UID_SMC_IPCLKPORT_L2CLK); + + /* + * (0) sleep or not + * + * Before sleep, SW must check sleep counters + * if sleep counter reaches 0 soon, :if expand("%") == ""|browse confirm w|else|confirm w|endif + * SW should skip sleep and just waits for wakeup interrupt + * + * (1) SW-controlled Power Domain Off + * SW domain power off done + */ +#if defined(__ICCARM__) +#warning "no support s5js100_sw_powerdomain_off" +#else + s5js100_sw_powerdomain_off(RFIP_BLK + MCPU_BLK); +#endif + S5JS100_PWR_DBG("1)SW domain power off\n"); + /* + * PMU, CMU initial setting + */ + putreg32(0x3, PMU_ALIVE_PROFILERCTRL); // BlackboxClr before sleep, BlackboxEn=1 + putreg32(0x3, PMU_SYS_PROFILERCTRL); // BlackboxClr before sleep, BlackboxEn=1 + putreg32((1u << 30) + (2u << 26) + (6u << 22), PMU_ALIVE_ALVSYSCTRLCFG); //CntLmtPWR_OFF_MIN=1,CntLmtPWR_STABLE=2(fast sim), CntLmtCKCHG=6 + // PMU_ALIVE_AlvSysCtrlCfg = (1u<<30)+(2u<<26)+(6u<<22)+(1u<<8);//CntLmtPWR_OFF_MIN=1,CntLmtPWR_STABLE=2(fast sim), CntLmtCKCHG=6, ReCalcUpDis=1 + S5JS100_PWR_DBG("2)PMU, CMU initial setting\n"); + + putreg32((1u << 8) + (2u << 4), PMU_ALIVE_TEMPMON_CFG0); //CntLmt_INTERVAL=1, CntLmt_TSU_CLK=2 + cur_temp = get_temp(); + S5JS100_PWR_DBG("2.1)current temperature : 0x%x\n", cur_temp); + putreg32(cur_temp, PMU_ALIVE_TEMPMON_CFG1); + putreg32(7, PMU_ALIVE_TEMPMON_CFG2); //Delta=30 + // PMU_ALIVE_TsuInt = (1u<<0) + (1u<<1); //UpIntEn=1, LowIntEn=1 : tested in TempMon wakeup + putreg32(30, PMU_ALIVE_RECALC_CFG1); //RcoRefCnt=3 ==> (30*4 + 1)ea RCO counted in RCO_TIMER_COMPENSATION + putreg32((SLPCLK_DIV * ((30 * 4) + 1)), PMU_ALIVE_RECALC_CFG0); //InitialDcxoRefCnt = (DCXO/814)*121 + + /* + * Wakeup source selection + */ + S5JS100_PWR_DBG("3)Wakeup source selection\n"); + + putreg32(_wkupsrc, PMU_ALIVE_WKUPSRCEN); // wakeup source enable + // it is just for simulation. + // in real SW, they are all enabled. + + if ((_wkupsrc & GPIO_ALV0) > 0) { //active high + gpio_eint_clear_pending(GPIO_ALIVE_0); + putreg32(0x4, 0xE000E280); + } + + if ((_wkupsrc & GPIO_ALV1) > 0) { //active low, pulse type + gpio_eint_clear_pending(GPIO_ALIVE_1); + putreg32(0x4, 0xE000E280); + } + + if ((_wkupsrc & APSLPCNT) > 0) { // AP sleep counter setting + + putreg32((1u << 5), PMU_ALIVE_APSLPCNT_CFG0); //5 : interrupt pending clear , 0: SW reset. + set_sleep_counter(pmu_info->time_msec); + S5JS100_PWR_DBG("PMU_ALIVE_APSLPCNT_CFG1 : 0x%x\n", *(unsigned int *)PMU_ALIVE_APSLPCNT_CFG1); + S5JS100_PWR_DBG("PMU_ALIVE_APSLPCNT_CFG2 : 0x%x\n", *(unsigned int *)PMU_ALIVE_APSLPCNT_CFG2); + putreg32((15u << 6) + (1u << 3) + (0u << 2) + (1u << 1) + (1u << 0), PMU_ALIVE_APSLPCNT_CFG0); + } + + if ((_wkupsrc & NSLEEP) > 0) { + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, (0x7 << 7), (0x7 << 7)); + putreg32((1u << 2) + (1u << 0) + (1u << 1), PMU_ALIVE_NSLEEP_CFG); + + } + + if ((_wkupsrc & TEMPMON) > 0) { + putreg32(((cur_temp + pmu_info->upper_temp) << 16) + ((cur_temp - pmu_info->lower_temp) << 0), PMU_ALIVE_TEMPMON_CFG3); + putreg32((1u << 0) + (1u << 1), PMU_ALIVE_TSUINT); + + } + + S5JS100_PWR_DBG("PD CDC clock on \n"); + + // SMC LPI lock + putreg32((1u << 1), PMU_SYS_DCGOVRD); + putreg32(0, PMU_SYS_SMC_LPI); + while ((getreg32(PMU_SYS_SMC_LPI) & 0x6) != 0x0) ; + putreg32(0x0, PMU_SYS_DCGOVRD); + S5JS100_PWR_DBG("PD CDC clock off \n"); + putreg32(0x1, PMU_ALIVE_SYSOFF); + putreg32(0x1, PMU_SYS_SYSCTRL_SYSOFF); + + while ((getreg32(0x85024018) >> 3) & 0x1) ; + + modifyreg32(PMU_ALIVE_PMIP_TCXO_LDO, 0x80000000, 0x0); + + // PMU STAUTS to be WARM BOOT + putreg32(WAKEUP_BOOT, PMU_ALIVE_BOOTFLAG); +#if defined( __GNUC__ ) + asm("dmb"); + asm("wfi"); +#else + __DMB(); + __WFI(); +#endif + + while (1) ; +} + +void pmu_nb_sleep(void) +{ + PMU_SLEEP_INFO pmu_info; + + pmu_info.wakeup_src = NSLEEP; + if (alv_wkup_src == GPIO_ALIVE_0) { + pmu_info.wakeup_src |= GPIO_ALV0; + } + if (alv_wkup_src == GPIO_ALIVE_1) { + pmu_info.wakeup_src |= GPIO_ALV1; + } + + pmu_info.alv0_gpio_int_type = wkup_type; + s5js100_pmu_sleep((PMU_SLEEP_INFO *)&pmu_info); +} + +void __attribute__((section(".ramfunc"))) s5js100_sflash_deepsleep(int on) +{ + volatile unsigned int count = 2000; + + if (on) { + modifyreg32(0x85020024, 0xFF000000, 0xB9000000); + putreg8(1, 0x8502005A); + } else { + modifyreg32(0x85020024, 0xFF000000, 0xAB000000); + putreg8(1, 0x8502005A); + } + + while (count--) { +#if defined( __GNUC__ ) + asm("nop"); +#else + __NOP(); +#endif + } +} +#if !defined(__ICCARM__) +void __attribute__((section(".ramfunc"))) s5js100_enter_exit_idle_drx(void) +{ +#if defined( __GNUC__ ) + asm("isb"); + asm("dsb"); + s5js100_sflash_deepsleep(1); + asm("dmb"); + asm("wfi"); + s5js100_sflash_deepsleep(0); + asm("isb"); + asm("dsb"); +#else + __ISB() + __DSB(); + s5js100_sflash_deepsleep(1); + __DMB(); + __WFI(); + s5js100_sflash_deepsleep(0); + __ISB() + __DSB(); +#endif +} +#endif + +#if !defined(__ICCARM__) +void __attribute__((section(".ramfunc"))) pmu_sleep_isr(void) +{ +#if defined(__ARMCC_VERSION) + while (1); +#else + asm("b ."); +#endif +} +#endif + + +char nbsleep_msg[] = "NBSLEEP CNT LSB=>"; +char ldo6_on[] = "LDO6 ON"; +char ldo6_off[] = "LDO6 OFF"; + + +/****************** Option Table ***********************/ +//#define PRINT_NBSLEEP_LOG +#define LDO_PWR_ON 0 + +// possible option : 1/1/1, 1/0/1, 1/1/0, 1/0/0, 0/0/0 +#define DCXO_IP_ON 0 +#define BUS_CLK_26MHZ 0 +#define SLEEP_CLK_32KHZ 0 + +#define PLL_OFF_OSC //always on +//#define LDO6_PWR_ALWAYS_ON + +#define LDO1_ON 0 +#define LDO2_ON 0 +#define LDO4_ON 0 +/*******************************************************/ +extern int cal_init(void); +extern int s5js100_dcxo_force_initialize(void); +extern void s5js100_sflash_reinit(void); + +/* BASE : condition 3 */ +/* default - DCXO_IP_ON */ +/* - BUS Clock 26MHz */ +/* - Sleep Clock 32Khz */ +//void __attribute__((section(".ramfunc"))) pmu_short_sleep(void) +void pmu_short_sleep(void) +{ + unsigned int i; + PMU_SLEEP_INFO pmu_info; + unsigned int nvic[8]; +#ifdef PRINT_NBSLEEP_LOG + char __buffer[12]; +#endif + +#ifdef PRINT_NBSLEEP_LOG + convert2hex(__buffer, getreg32(0x81000000 + 0xE8)); + direct_uart(nbsleep_msg, sizeof(nbsleep_msg)); + direct_uart(__buffer, sizeof(__buffer)); +#endif + + pmu_info.wakeup_src = NSLEEP; + if (alv_wkup_src == GPIO_ALIVE_0) { + pmu_info.wakeup_src |= GPIO_ALV0; + } + if (alv_wkup_src == GPIO_ALIVE_1) { + pmu_info.wakeup_src |= GPIO_ALV1; + } + + //BUCK1, LDO0 on + modifyreg32(PMU_ALIVE_PMIPCTRL_OVRD, (1u << 0) + (1u << 1) + (1u << 7) + (1u << 8), (1u << 0) + (1u << 1) + (0 << 7) + (0 << 8)); + + //BUCK0, LDO3 on + modifyreg32(PMU_ALIVE_PMIPCTRL_OVRD, (1u << 4) + (1u << 6) + (1u << 11) + (1u << 13), (1u << 4) + (1u << 6) + (0 << 11) + (0 << 13)); + + /* LDO 1/2/4 ON/OFF */ + // LDO1 ON/OFF + modifyreg32(PMU_ALIVE_PMIPCTRL_OVRD, (1u << 2), LDO1_ON << 2); + // LDO2 ON/OFF + modifyreg32(PMU_ALIVE_PMIPCTRL_OVRD, (1u << 3), LDO2_ON << 3); + // LDO4 ON/OFF + modifyreg32(PMU_ALIVE_PMIPCTRL_OVRD, (1u << 5), LDO4_ON << 5); + + pmu_sys_cdc_clk_en(ON); //CDC ON + + putreg32((1u << 30) + (2u << 26) + (6u << 22), PMU_ALIVE_ALVSYSCTRLCFG); + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, 0x3ff, 0x3ff); + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, 1u << 6, 0); // do not enable clamp cells + + // Do PMIP off + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, 1u << 3, LDO_PWR_ON << 3); + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, (1u << 2), (DCXO_IP_ON << 2)); //DCXO_IP + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, (1u << 1), (BUS_CLK_26MHZ << 1)); //BUS Clock 26MHZ + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, (1u << 0), (SLEEP_CLK_32KHZ << 0)); //sleep_clock 32KHz + + putreg32((1u << 1) + (1u << 0), PMU_ALIVE_PROFILERCTRL); //BlackboxClr=1, BlackboxEn=1 + putreg32((1u << 1) + (1u << 0), PMU_SYS_PROFILERCTRL); //BlackboxClr=1, BlackboxEn=1 + + putreg32((1u << 1), PMU_SYS_ACPUCTRL_CFG0); //EfuseSenseReqDis=1 + + putreg32(pmu_info.wakeup_src, PMU_ALIVE_WKUPSRCEN); + modifyreg32(PMU_ALIVE_ALVSYSCTRLCFG, (0x7 << 7), (0x7 << 7));// [0] :wakeup interrupt enable , [1]: sys_valid_int_en + putreg32((1u << 2) + (1u << 0) + (1u << 1), PMU_ALIVE_NSLEEP_CFG);// [0] :wakeup interrupt enable , [1]: sys_valid_int_en + + if ((pmu_info.wakeup_src & APSLPCNT) > 0) { // AP sleep counter setting + putreg32((1u << 5), PMU_ALIVE_APSLPCNT_CFG0);//5 : interrupt pending clear , 0: SW reset. + set_sleep_counter(pmu_info.time_msec); + putreg32((15u << 6) + (1u << 3) + (0u << 2) + (1u << 1) + (1u << 0), PMU_ALIVE_APSLPCNT_CFG0); //IgnoreReCalcLmt=15,IntMask_n=1,ReCalcUpdateMask=0,En=1,SwRst_n=1 + } + + for (i = 0; i < 8; i++) { + nvic[i] = getreg32(0xE000E100 + (0x4 * i)); + putreg32(nvic[i], 0xE000E180 + (0x4 * i));//disable all interrupt + } + + NVIC_EnableIRQ(S5JS100_IRQ_SLEEP); //NBSLEEP + alvgpio_interrupt_enable(); + + while (getreg32(PMU_SYS_MCPUMON) != 1); // waits for MCPU WFI + + putreg32(0x4, 0xE000E280); + while (getreg32(0xE000E200 + 0x4) & (0x80)) { + putreg32(0x80, 0xE000E284);//clear SLEEP pending, should be clear by CP first + } +#ifdef PRINT_NBSLEEP_LOG + convert2hex(__buffer, getreg32(PMU_ALIVE_ALVSYSCTRLCFG)); + direct_uart(__buffer, sizeof(__buffer)); +#endif + + // PMU could control on/off of LDO6 if LDO6 SwMuxSel was zero. + // PMU power off LDO6 + modifyreg32(PMU_ALIVE_PMIP_TCXO_LDO, 0x80000000, 0x0); + + *(volatile unsigned *)(0x82000100) = 0x018c0d01; //system mux change PLL -> DCXO, PLL off + + putreg32(0x1, PMU_ALIVE_SYSOFF); + putreg32(0x1, PMU_SYS_SYSCTRL_SYSOFF); + putreg32(1, PMU_ALIVE_BOOTFLAG); +#if defined(__ICCARM__) +#warning "ICCARM no support idle drx" +#else + s5js100_enter_exit_idle_drx(); //cpu wfi +#endif + while (getreg32(PMU_SYS_ACPUCTRL_FSM) != 0x14151600 && getreg32(PMU_SYS_ACPUCTRL_FSM) != 0); + + /* DCXO ON */ + if (!(DCXO_IP_ON)) { + s5js100_dcxo_force_initialize(); /* DCXO off -> on after short_sleep */ + } + + cal_init(); + s5js100_sflash_reinit(); + + putreg32(0x0, PMU_ALIVE_SYSOFF); + putreg32(0x0, PMU_SYS_SYSCTRL_SYSOFF); + + /* AP2CP mailbox interrupt generation */ + /* MCPU back to work */ + putreg32(0x3F80, PMU_ALIVE_PMIPCTRL_OVRD); + + //wait MCPU wfi break + // while(PMU_SYS_McpuMon == 0x1); + putreg32(0x2, 0x85023020); + putreg32(0x2, 0x8502301C); + + for (i = 0; i < 8; i++) { + putreg32(nvic[i], 0xE000E100 + (0x4 * i)); //enable all interrupt + } + + NVIC_DisableIRQ(S5JS100_IRQ_SLEEP); + + pmu_sys_cdc_clk_en(OFF); //CDC OFF + gpio_eint_mask(alv_wkup_src); //IntEn=1 + alvgpio_interrupt_enable(); +} + +void pmu_test_auto(int sleep_time_msec) +{ + PMU_SLEEP_INFO pmu_info; + + S5JS100_PWR_DBG("%s...\n", __func__); + + pmu_info.wakeup_src = APSLPCNT; + pmu_info.time_msec = sleep_time_msec; + s5js100_pmu_sleep((PMU_SLEEP_INFO *)&pmu_info); +} + +unsigned int get_wakeup_src_status(void) +{ + return getreg32(PMU_ALIVE_WKUPINTSNAPSHOT); +} + +void mcpu_reset_dump(void) +{ + mcpu_reset(); + s5js100_pmu_init(); + *((unsigned int *)(TCM_BASE + 0x1800 - 0x40)) = 0x55500000; + SCB_CleanDCache(); + putreg32(0x1, SYS_CFG_MCPU_HALTN); +} + diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.h new file mode 100644 index 0000000000..9dd92e3fa9 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_pwr.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_PWR_H__ +#define __S5JS100_PWR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PWR_DSTOP, + PWR_STOP, +} PWR_MODE; + +typedef enum { + MCPU_BLK = (0x1 << 0), + RFIP_BLK = (0x1 << 1), +} PWR_BLK; +typedef enum { + GPIO_ALIVE_0, + GPIO_ALIVE_1, + GPIO_ALIVE_NONE, +} PORT_NUM; + +typedef enum { + OUTPUT = (0x1 << 0), + INPUT = (0x1 << 1), +} PORT_DIR; + +typedef enum { + PULL_DIS = 0, + PULL_DOWN = 1, + PULL_UP = 3, +} PUD_CON; + +typedef enum { + LOWLEVEL, + HIGHLEVEL, + FALLING, + RISING, +} FILTER_TYPE; + +// wakeup source define +#define TEMPMON (1<<4) +#define GPIO_ALV1 (1<<3) +#define GPIO_ALV0 (1<<2) +#define APSLPCNT (1<<1) +#define NSLEEP (1<<0) + +typedef enum { + MCPU_CP = 0, + MCPU_GNSS = 1, + MCPU_NONE = -1, +} MCPU_MODE; + +#define GNSS_BIN_BASE (0x4063C000) +#define CP_BIN_BASE (0x40050000) +#define TCM_BASE (0x20000000) +#define MCPU_BINARY_SIZE (0x20000) + +extern int s5js100_pwr_dbg_on; +extern MCPU_MODE mcpu_device_mode; + + +#define WAKEUP_BOOT 0 +#define COLD_BOOT 1 + + +typedef struct { + unsigned int wakeup_src; + unsigned int wakeup_status; + FILTER_TYPE alv0_gpio_int_type; + FILTER_TYPE alv1_gpio_int_type; + unsigned int time_msec; + unsigned int upper_temp; + unsigned int lower_temp; + unsigned int nbiot_time_msec; +} PMU_SLEEP_INFO; + + +extern unsigned int get_bootflag(void); +extern void pmu_nb_sleep(void); +extern void pmu_short_sleep(void); +extern void s5js100_pmu_sleep(PMU_SLEEP_INFO *info); +extern void mcpu_reset(void); +extern void mcpu_init(MCPU_MODE device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_rtos.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_rtos.h new file mode 100644 index 0000000000..ea7b7168d1 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_rtos.h @@ -0,0 +1,43 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_RTOS_H__ +#define __S5JS100_RTOS_H__ +#define enable_icache() SCB_EnableICache() +#define enable_dcache() SCB_EnableDCache() +#define disable_icache() SCB_DisableICache() +#define disable_dcache() SCB_DisableDCache() + +/* + * I-CACHE operations + */ +#define invalidate_icache() SCB_InvalidateICache() + +/* + * D-CACHE operations + */ +#define invalidate_dcache() SCB_InvalidateDCache() +#define invalidate_dcache_by_addr(addr,size) SCB_InvalidateDCache_by_Addr(addr, size) +#define clean_dcache() SCB_CleanDCache() +#define clean_dcache_by_addr(addr, size) SCB_CleanDCache_by_Addr(addr, size) +#define clean_invalidate_dcache() SCB_CleanInvalidateDCache() +#define clean_invalidate_dcache_by_addr(addr, size) SCB_CleanInvalidateDCache_by_Addr(addr, size) + + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.c new file mode 100644 index 0000000000..2651bd294f --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.c @@ -0,0 +1,301 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include "cmsis_os.h" + +#include "s5js100_type.h" +#include "s5js100.h" +#include "s5js100_watchdog.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +// REGISTERS +#define rWDOG_CTRL 0x00 +#define bWDOG_CNT_EN (2) +#define bWDOG_PCLK_EN (1) +#define bWDOG_WCLK_EN (0) + +#define rWDOG_LOAD_VAL 0x04 +#define rWDOG_LOAD 0x08 +#define rWDOG_RESET_REQ_EN 0x0C +#define rWDOG_INT_EN 0x10 +#define rWDOG_INT_STAT_RAW 0x14 +#define rWDOG_INT_STAT_MASKED 0x18 +#define rWDOG_INT_CLR 0x1C +#define rWDOG_CNT_UPD_EN 0x20 +#define rWDOG_CNT_VAL 0x24 +#define rWDOG_RESET_REQN_STAT 0x28 +#define rWDOG_LOAD_VAL_DIFF 0x2C +#define rWDOG_BLK_CTRL 0x800 + +#define EXT_SLPCLK 32768 + +#ifdef CONFIG_S5JS100_WATCHDOG +/**************************************************************************** + * Private Types + ****************************************************************************/ +struct s5js100_watchdog_priv_s { + uint32_t base_addr; + int irq_id; +}; + +static FAR struct s5js100_watchdog_priv_s s5js100_watchdog_priv = { + .base_addr = (S5JS100_WDT_BASE + 0x000), + .irq_id = S5JS100_IRQ_WDG, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static uint32_t s5js100_watchdog_getclock(void) +{ + /* TODO: get TCLKB from CLK DRIVER */ + return EXT_SLPCLK; +} +#endif /* CONFIG_S5JS100_WATCHDOG */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef CONFIG_S5JS100_WATCHDOG + +/**************************************************************************** + * Name: s5js100_watchdog_disable + * + * Description: + * Disable the watchdog timer. The S5J always boots with the watchdog + * timer enabled at timeout of 10 - 20 seconds by the second stage boot + * loader to detect any boot failure. So, the watchdog timer must be + * disabled as part of the start up logic. + * + ****************************************************************************/ +void s5js100_watchdog_disable(void) +{ + putreg32(0, S5JS100_WDT_BASE + rWDOG_CNT_UPD_EN); + modifyreg32(S5JS100_WDT_BASE + rWDOG_CTRL, (1 << bWDOG_CNT_EN), 0); +} + +#else /* CONFIG_S5JS100_WATCHDOG */ + +/**************************************************************************** + * Name: s5js100_watchdog_disable + * + * Description: + * Disable the watchdog timer. The S5J always boots with the watchdog + * timer enabled at timeout of 10 - 20 seconds by the second stage boot + * loader to detect any boot failure. So, the watchdog timer must be + * disabled as part of the start up logic. + * + ****************************************************************************/ +void s5js100_watchdog_disable(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(0, priv->base_addr + rWDOG_CNT_UPD_EN); + modifyreg32(priv->base_addr + rWDOG_CTRL, (1 << bWDOG_CNT_EN), 0); +} + +/**************************************************************************** + * Name: s5js100_watchdog_enable + * + * Description: + * Enable watchdog operation. + * Should be correctly configured before enabling. + * + ****************************************************************************/ +void s5js100_watchdog_enable(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(1, priv->base_addr + rWDOG_CNT_UPD_EN); + modifyreg32(priv->base_addr + rWDOG_CTRL, 0, (0x1 << bWDOG_CNT_EN)); +} + +/**************************************************************************** + * Name: s5js100_watchdog_reset_disable + * + * Description: + * When WD timer expires, it can issue HW reset. + * This function disables reset feature. + * Watchdog will be reloaded with value written in reload register. + * and continue its operation. + * + ****************************************************************************/ +void s5js100_watchdog_reset_disable(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(0, priv->base_addr + rWDOG_RESET_REQ_EN); +} + +/**************************************************************************** + * Name: s5js100_watchdog_reset_enable + * + * Description: + * When WD timer expires, it can issue HW reset. + * This function enables reset feature. + * + ****************************************************************************/ +void s5js100_watchdog_reset_enable(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(1, priv->base_addr + rWDOG_RESET_REQ_EN); + putreg32(1 << 1, 0x82020018); + +} + + +void s5js100_watchdog_ack_irq(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(0, priv->base_addr + rWDOG_INT_CLR); +} + +/**************************************************************************** + * Name: s5js100_watchdog_irq_disable + * + * Description: + * When WD timer expires, it can issue interrupt. + * This function disables reset feature. + * + ****************************************************************************/ +void s5js100_watchdog_irq_disable(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(0, priv->base_addr + rWDOG_INT_EN); +} + +/**************************************************************************** + * Name: s5js100_watchdog_irq_enable + * + * Description: + * When WD timer expires, it can issue interrupt. + * This function enables reset feature. + * + ****************************************************************************/ +void s5js100_watchdog_irq_enable(FAR struct s5js100_watchdog_priv_s *priv) +{ + putreg32(1, priv->base_addr + rWDOG_INT_EN); +} + +int s5js100_watchdog_setisr(FAR struct s5js100_watchdog_priv_s *priv, xcpt_t handler, void *arg) +{ + irq_attach(priv->irq_id, handler, arg); + + if (handler == NULL && arg == NULL) { + up_disable_irq(priv->irq_id); + } else { + up_enable_irq(priv->irq_id); + } + + return OK; +} + + +/**************************************************************************** + * Name: s5js100_watchdog_set_reload_val + * + * Description: + * When WD timer expires, if reset is disabled, will be reloaded with value + * defined by this function call. + * + ****************************************************************************/ +void s5js100_watchdog_set_reload_val(FAR struct s5js100_watchdog_priv_s *priv, unsigned int time_ms) +{ + uint32_t slp_clk = s5js100_watchdog_getclock(); + uint32_t load_value; + + load_value = (time_ms * slp_clk) / 1000; + putreg32(load_value, priv->base_addr + rWDOG_LOAD_VAL); + putreg32(0x1, priv->base_addr + rWDOG_LOAD); +} + +/**************************************************************************** + * Name: s5js100_watchdog_set_load_val_diff + * + * Description: + * Funtion s5js100_watchdog_set_load_val_diff set LOAD_VAL_DIFF value. + * This value sets the difference between interrupt assertion time and + * the reset request assertion time. The interrupt assertion occurs before + * the reset request as this value. This value should be stable before writing + * 1 to LOAD register. + * + ****************************************************************************/ +void s5js100_watchdog_set_load_val_diff(FAR struct s5js100_watchdog_priv_s *priv, unsigned int time_ms) +{ + uint32_t slp_clk = s5js100_watchdog_getclock(); + uint32_t load_diff; + + load_diff = (time_ms * slp_clk) / 1000; + putreg32(load_diff, priv->base_addr + rWDOG_LOAD_VAL_DIFF); +} + +/**************************************************************************** + * Name: s5js100_watchdog_get_curr + * + * Description: + * Function s5js100_watchdog_get_curr returns current WD counter value. + ****************************************************************************/ +unsigned int s5js100_watchdog_get_curr(FAR struct s5js100_watchdog_priv_s *priv) +{ + uint32_t slp_clk = s5js100_watchdog_getclock(); + uint32_t load_value; + + load_value = getreg32(priv->base_addr + rWDOG_CNT_VAL); + + return ((load_value * 1000) / slp_clk); +} + +/**************************************************************************** + * Name: s5js100_watchdog_set_curr + * + * Description: + * Function s5js100_watchdog_set_curr sets immediately current WD counter value. + * Use this function to set initial WD timer value before running operation. + ****************************************************************************/ +void s5js100_watchdog_set_curr(FAR struct s5js100_watchdog_priv_s *priv, unsigned int curr_val) +{ + putreg32(curr_val, priv->base_addr + rWDOG_LOAD_VAL); + putreg32(0x1, priv->base_addr + rWDOG_LOAD); +} + +/**************************************************************************** + * Name: s5js100_watchdog_clear_int + * + * Description: + * Function s5js100_watchdog_clear_int clears pending interrupt flag. + * Used after WD IRQ service routine completes its operation. + ****************************************************************************/ +void s5js100_watchdog_clear_int(FAR struct s5js100_watchdog_priv_s *priv) +{ + // putreg32(0xffffffff, S5J_WDT_BASE + WTCLRINT); +} + +FAR struct s5js100_watchdog_priv_s *s5js100_watchdog_init(void) +{ + FAR struct s5js100_watchdog_priv_s *priv = NULL; + + /* some clock setting ? */ + priv = &s5js100_watchdog_priv; + return priv; +} + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.h new file mode 100644 index 0000000000..4c6c04d579 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/s5js100_watchdog.h @@ -0,0 +1,77 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 __S5JS100_WATCHDOG_H +#define __S5JS100_WATCHDOG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +#ifndef CONFIG_S5JS100_WATCHDOG +void s5js100_watchdog_disable(void); + +#else /* CONFIG_S5JS100_WATCHDOG */ +struct s5js100_watchdog_priv_s; + +void s5js100_watchdog_disable(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_enable(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_reset_disable(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_reset_enable(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_irq_disable(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_irq_enable(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_clk_set(unsigned int prescaler, unsigned int divider); +void s5js100_watchdog_set_reload_val(FAR struct s5js100_watchdog_priv_s *priv, unsigned int time_ms); +void s5js100_watchdog_set_load_val_diff(FAR struct s5js100_watchdog_priv_s *priv, unsigned int time_ms); +unsigned int s5js100_watchdog_get_curr(FAR struct s5js100_watchdog_priv_s *priv); +void s5js100_watchdog_set_curr(FAR struct s5js100_watchdog_priv_s *priv, unsigned int curr_val); +void s5js100_watchdog_clear_int(FAR struct s5js100_watchdog_priv_s *priv); +FAR struct s5js100_watchdog_priv_s *s5js100_watchdog_init(void); + +#endif + +#ifdef CONFIG_WATCHDOG +int s5js100_watchdog_initialize(FAR const char *devpath); +void s5js100_watchdog_autoping(void *arg); +FAR struct watchdog_lowerhalf_s *s5js100_watchdog_lowerhalf(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __S5JS100_WATCHDOG_H */ diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_api.c new file mode 100644 index 0000000000..bf2365c4c1 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_api.c @@ -0,0 +1,314 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +#if DEVICE_SERIAL + +// math.h required for floating point operations for baud rate calculation +#include +#include +#include +#include + +#include "device.h" +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PinNames.h" +#include "mbed_error.h" +#include "gpio_api.h" + +#include "mbed_assert.h" + + + +void usi_serial_init(void *obj, PinName tx, PinName rx); +void pl011_serial_init(void *obj, PinName tx, PinName rx); +void dummy_serial_init(void *obj, PinName tx, PinName rx); + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ + +static const PinMap PinMap_UART_TX[] = { + {UART_TX0, UART_0, UART_TX0}, + {UART_TX1, UART_1, UART_TX1}, + {UART_TX2, UART_2, UART_TX2}, + {UART_TX3, UART_3, UART_TX3}, + {UART_TX4, UART_4, UART_TX4}, + {UART_TX5, UART_5, UART_TX5}, + {NC, NC, NC} +}; +static const PinMap PinMap_UART_RX[] = { + {UART_RX0, UART_0, UART_RX0}, + {UART_RX1, UART_1, UART_RX1}, + {UART_RX2, UART_2, UART_RX2}, + {UART_RX3, UART_3, UART_RX3}, + {UART_RX4, UART_4, UART_RX4}, + {UART_RX5, UART_5, UART_RX5}, + {NC, NC, NC} +}; + +/* +static const PinMap PinMap_UART_CTS[] = { + {UART0_CTS, UART_0, UART0_CTS}, + {UART1_CTS, UART_1, UART1_CTS}, + {UART2_CTS, UART_2, UART2_CTS}, + {UART3_CTS, UART_3, UART3_CTS}, + {NC, NC, NC} +}; + +static const PinMap PinMap_UART_RTS[] = { + {UART0_RTS, UART_0, UART0_RTS}, + {UART1_RTS, UART_1, UART1_RTS}, + {UART2_RTS, UART_2, UART2_RTS}, + {UART3_RTS, UART_3, UART3_RTS}, + {NC, NC, NC} +}; +*/ + + +/* Used in platform/mbed_retarget.cpp */ +/* What shall I do with it??? What is it for? */ +int stdio_uart_inited = 0; +serial_t stdio_uart; + + +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + struct serial_s *priv = (struct serial_s *)obj; + + // determine the UART to use ??? + // Shall we check if it is already allocated ??? + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + if ((PinName)uart == NC) { + error("Serial pinout mapping failed"); + } + if ((PinName)uart_tx != NC) { + s5js100_configgpio(pinmap_find_function(tx, PinMap_UART_TX)); + } + + if ((PinName)uart_rx != NC) { + s5js100_configgpio(pinmap_find_function(rx, PinMap_UART_RX)); + } + + /* BAD Pointer assignment!!! Better to redesign*/ + priv->uart = (void *)uart; + switch (uart) { + case UART_0: + case UART_1: + usi_serial_init(obj, tx, rx); + break; + + case UART_2: + case UART_3: + pl011_serial_init(obj, tx, rx); + break; + + case UART_4: + case UART_5: + dummy_serial_init(obj, tx, rx); + break; + } + + // set default baud rate and format + obj->ops.serial_baud(obj, 115200); + obj->ops.serial_format(obj, 8, ParityNone, 1); + + if (uart == STDIO_UART) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) +{ + //needs release serial +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) +{ + obj->ops.serial_baud(obj, baudrate); + +} + +void serial_format(serial_t *obj, int data_bits, + SerialParity parity, int stop_bits) +{ + obj->ops.serial_format(obj, data_bits, parity, stop_bits); +} + + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + obj->ops.serial_irq_handler(obj, handler, id); +} + + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + obj->ops.serial_irq_set(obj, irq, enable); +} + +#if DEVICE_SERIAL_FC +void serial_set_flow_control(serial_t *obj, FlowControl type, + PinName rxflow, PinName txflow) +{ + struct serial_s *priv = (struct serial_s *)obj; + + UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS); + UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS); + UARTName uart = (UARTName)pinmap_merge(uart_rts, uart_cts); + if ((PinName)uart == NC) { + error("Serial pinout mapping failed"); + } + + if ((int)uart != (int)priv->uart) { + error("Serial pinout mapping failed"); + } + + + if (type == FlowControlRTS) { + // Enable RTS + MBED_ASSERT(uart_rts != (UARTName)NC); + // Enable the pin for RTS function + s5js100_configgpio(pinmap_find_function(rxflow, PinMap_UART_RTS)); + } + if (type == FlowControlCTS) { + // Enable CTS + MBED_ASSERT(uart_cts != (UARTName)NC); + // Enable the pin for CTS function + s5js100_configgpio(pinmap_find_function(txflow, PinMap_UART_CTS)); + } + if (type == FlowControlRTSCTS) { + // Enable CTS & RTS + MBED_ASSERT(uart_rts != (UARTName)NC); + MBED_ASSERT(uart_cts != (UARTName)NC); + // Enable the pin for CTS function + s5js100_configgpio(pinmap_find_function(txflow, PinMap_UART_CTS)); + // Enable the pin for RTS function + s5js100_configgpio(pinmap_find_function(rxflow, PinMap_UART_RTS)); + } + + + obj->ops.serial_set_flow_control(obj, type, rxflow, txflow); +} +#endif + + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) +{ + return obj->ops.serial_getc(obj); +} + +void serial_putc(serial_t *obj, int c) +{ + obj->ops.serial_putc(obj, c); +} + +int serial_readable(serial_t *obj) +{ + return obj->ops.serial_readable(obj); +} + +int serial_writable(serial_t *obj) +{ + return obj->ops.serial_writable(obj); +} + + +/* Shall it be ever used ??? +void serial_clear(serial_t *obj) +{ + if (obj->index < 2) + { + USI_PTR(obj->uart)->URXH = 0x00; + while ((getreg32(0x83015018) & UART_UFSTAT_TX_FIFO_FULL)); + while ((getreg32(0x83015018) & UART_UFSTAT_TX_FIFO_COUNT_MASK)); + putreg8('C', 0x83015020); + while ((getreg32(0x83015018) & UART_UFSTAT_TX_FIFO_FULL)); + while ((getreg32(0x83015018) & UART_UFSTAT_TX_FIFO_COUNT_MASK)); + putreg8('C', 0x83015020); + putreg8('C', 0x83015020); + putreg8('C', 0x83015020); + putreg8('C', 0x83015020); + putreg8('C', 0x83015020); + putreg8('C', 0x83015020); + } + else + { + UART_PTR(obj->uart)->DR = 0x00; + while (UART_PTR(obj->uart)->FR & (1u << 5)); + while (UART_PTR(obj->uart)->FR & (1u << 7)); + UART_PTR(obj->uart)->DR = 'C'; + while (UART_PTR(obj->uart)->FR & (1u << 5)); + while (UART_PTR(obj->uart)->FR & (1u << 7)); + UART_PTR(obj->uart)->DR = 'C'; + UART_PTR(obj->uart)->DR = 'C'; + UART_PTR(obj->uart)->DR = 'C'; + UART_PTR(obj->uart)->DR = 'C'; + UART_PTR(obj->uart)->DR = 'C'; + UART_PTR(obj->uart)->DR = 'C'; + } +} +*/ + +/* Used in + * features/unsupported/tests/libs/SerialHalfDuplex/SerialHalfDuplex.cpp + * What is it for? + */ +void serial_pinout_tx(PinName tx) +{ + pinmap_pinout(tx, PinMap_UART_TX); +} + + +/* Serial break may never be used. + * In general set TX to "0". + * However - shall we? + */ + +void serial_break_set(serial_t *obj) +{ +} + +void serial_break_clear(serial_t *obj) +{ +} + + +/* pinmap test entry */ + +const PinMap *serial_tx_pinmap() +{ + return PinMap_UART_TX; +} + +const PinMap *serial_rx_pinmap() +{ + return PinMap_UART_RX; +} + +#endif // DEVICE_SERIAL diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_dummy_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_dummy_api.c new file mode 100644 index 0000000000..979761edea --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_dummy_api.c @@ -0,0 +1,120 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + +#if DEVICE_SERIAL + +// math.h required for floating point operations for baud rate calculation +#include +#include +#include +#include + +#include "device.h" +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PinNames.h" +#include "mbed_error.h" +#include "gpio_api.h" + + +void (*dummy_uart_write_redirect)(int c); + + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +static void dummy_serial_baud(void *obj, int baudrate) +{ +} + +static void dummy_serial_format(void *obj, int data_bits, + SerialParity parity, int stop_bits) +{ +} + +static void dummy_serial_irq_handler(void *obj, uart_irq_handler handler, uint32_t id) +{ +} + +static void dummy_serial_irq_set(void *obj, SerialIrq irq, uint32_t enable) +{ +} + + +static int dummy_serial_readable(void *obj) +{ + return 0; +} + +static int dummy_serial_writable(void *obj) +{ + return 1; +} + + +static int dummy_serial_getc(void *obj) + +{ + + return 0; +} + +static void dummy_serial_putc(void *obj, int c) +{ + if (dummy_uart_write_redirect) { + dummy_uart_write_redirect(c); + } +} + +#if DEVICE_SERIAL_FC +static void dummy_serial_set_flow_control(struct serial_s *obj, FlowControl type, + PinName rxflow, PinName txflow) +{ + error("dummy flow control is not implenemted"); +} +#endif + +void dummy_serial_init(void *obj, PinName tx, PinName rx) +{ + struct serial_s *priv = (struct serial_s *)obj; + + switch ((int)priv->uart) { + case UART_4: + priv->index = DUMMY_UART0_ID; + break; + case UART_5 : + priv->index = DUMMY_UART1_ID; + break; + } + + priv->ops.serial_baud = dummy_serial_baud; + priv->ops.serial_format = dummy_serial_format; + priv->ops.serial_irq_handler = dummy_serial_irq_handler; + priv->ops.serial_irq_set = dummy_serial_irq_set; + priv->ops.serial_putc = dummy_serial_putc; + priv->ops.serial_writable = dummy_serial_writable; + priv->ops.serial_getc = dummy_serial_getc; + priv->ops.serial_readable = dummy_serial_readable; +#if DEVICE_SERIAL_FC + priv->ops.serial_set_flow_control = dummy_serial_set_flow_control; +#endif + dummy_uart_write_redirect = NULL; +} + + +#endif // DEVICE_SERIAL diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_pl011_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_pl011_api.c new file mode 100644 index 0000000000..350b5558ec --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_pl011_api.c @@ -0,0 +1,328 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + +#if DEVICE_SERIAL + +// math.h required for floating point operations for baud rate calculation +#include +#include +#include +#include + +#include "device.h" +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PinNames.h" +#include "mbed_error.h" +#include "mbed_assert.h" +#include "gpio_api.h" + +#define UART_PTR(ptr) ((S5JS100_UART_TypeDef *)(ptr)) +static uart_irq_handler irq_handler[PL011_UART_MAX]; + +struct serial_context_data_s { + uint32_t serial_irq_id; + gpio_t sw_rts, sw_cts; + uint8_t count, rx_irq_set_flow, rx_irq_set_api; +}; + +static struct serial_context_data_s uart_data[PL011_UART_MAX]; + + + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(t_pl011_ports_enum index, + UARTName uart) +{ + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(uart); + int irq_type = 0xFFFF; /* type none */ + + if (!(p_PL011_UART->FR & 1u << 5)) { + if (p_PL011_UART->IMSC & 1u << 5) { + irq_type = TxIrq; + } + } + + if (p_PL011_UART->MIS & (1u << 4) || p_PL011_UART->MIS & (1u << 6)) { + /* + Rx Interrupt & Rx Timeout Interrupt + The receive timeout interrupt is asserted when the receive FIFO is not empty, + and no further data is received over a 32-bit period. + */ + irq_type = RxIrq; + } + + if (irq_type == RxIrq) { + if (uart_data[index].rx_irq_set_api) { + (irq_handler[index])(uart_data[index].serial_irq_id, irq_type); + } + } + + if (irq_type == TxIrq) { + /* Clear the TX interrupt Flag */ + /* UART TX */ + } else { + /* Clear the Rx interupt Flag */ + /* UART RX */ + } +} + + +static void uart2_irq() +{ + uart_irq(PL011_UART0_ID, UART_2); +} + +static void uart3_irq() +{ + uart_irq(PL011_UART1_ID, UART_3); +} + + +static void pl011_serial_irq_set_internal(void *obj, SerialIrq irq, uint32_t enable) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + + + + if (enable) { + p_PL011_UART->IMSC = 0x50; //interrupt by Rx Timeout & Rx (for fifo mode) + + } else if ((irq == TxIrq) || (uart_data[priv->index].rx_irq_set_api + + uart_data[priv->index].rx_irq_set_flow == 0)) { + p_PL011_UART->IMSC = 0; //interrupt by Rx Timeout & Rx (for fifo mode) + + } +} + + + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +static void pl011_serial_baud(void *obj, int baudrate) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + + uint32_t sclk = 0; + float div, frac; + switch (priv->index) { + case PL011_UART0_ID: + sclk = cal_clk_getrate(d1_uart0); + break; + + case PL011_UART1_ID: + sclk = cal_clk_getrate(d1_uart1); + break; + + default: + MBED_ASSERT(false); + } + + div = ((float)sclk / (float)(baudrate * 16)); + frac = (uint32_t)(((div - (int32_t)div) * 64)); + + p_PL011_UART->IBRD = (uint32_t)div; + p_PL011_UART->FBRD = (uint32_t)frac; +} + +static void pl011_serial_format(void *obj, int data_bits, + SerialParity parity, int stop_bits) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + uint32_t reg; + + switch (data_bits) { + case 5: + reg = 0; + break; + case 6: + reg = 1 << 5; + break; + case 7: + reg = 2 << 5; + break; + default: + reg = 3 << 5; + } + + switch (parity) { + case ParityNone: + reg |= 0; + break; + case ParityOdd: + reg |= 4; + break; + case ParityEven: + reg |= 6; + break; + case ParityForced1: + reg |= 5; + break; + case ParityForced0: + reg |= 7; + break; + } + + if (stop_bits == 2) { + reg |= 1 << 3; + } + + + /* Enable FIFO */ + reg |= 1 << 4; + + + p_PL011_UART->LCRH = reg; +} + +static void pl011_serial_irq_handler(void *obj, uart_irq_handler handler, uint32_t id) +{ + struct serial_s *priv = (struct serial_s *)obj; + + irq_handler[priv->index] = handler; + uart_data[priv->index].serial_irq_id = id; +} + + + + +static void pl011_serial_irq_set(void *obj, SerialIrq irq, uint32_t enable) +{ + struct serial_s *priv = (struct serial_s *)obj; + + if (RxIrq == irq) { + uart_data[priv->index].rx_irq_set_api = enable; + } + + pl011_serial_irq_set_internal(obj, irq, enable); +} + + +static int pl011_serial_readable(void *obj) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + return !(p_PL011_UART->FR & (1u << 4)); +} + +static int pl011_serial_writable(void *obj) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + return !(p_PL011_UART->FR & (1u << 5)); +} + + +static int pl011_serial_getc(void *obj) + +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + int data; + while (!serial_readable(priv)); + data = p_PL011_UART->DR & 0xFF; + + return data; +} + +static void pl011_serial_putc(void *obj, int c) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + + while (!serial_writable(priv)); + p_PL011_UART->DR = c; +} + +#if DEVICE_SERIAL_FC +static void pl011_serial_set_flow_control(struct serial_s *obj, FlowControl type, + PinName rxflow, PinName txflow) +{ + error("pl011 flow control is not implenemted"); +} +#endif + +void pl011_serial_init(void *obj, PinName tx, PinName rx) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_UART_TypeDef *p_PL011_UART = UART_PTR(priv->uart); + + /* Declare a variable of type IRQn, initialise to 0 */ + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + + switch ((int)priv->uart) { + case UART_2: + irq_n = S5JS100_IRQ_UART0; + vector = (uint32_t)&uart2_irq; + priv->index = PL011_UART0_ID; + break; + case UART_3 : + irq_n = S5JS100_IRQ_UART1; + vector = (uint32_t)&uart3_irq; + priv->index = PL011_UART1_ID; + break; + } + + + /* Enable UART and RX/TX path*/ + p_PL011_UART->CR = 0x301; + /* RX/TX fifo half full interrupt*/ + p_PL011_UART->IFLS = (2 << 3) | 2; + /* clear all interrupts mask */ + p_PL011_UART->IMSC = 0x0; + /* Clear all interripts */ + p_PL011_UART->ICR = 0x7FF; + /* MODESEL as default UART*/ + p_PL011_UART->MODESEL = 0x0; + + priv->ops.serial_baud = pl011_serial_baud; + priv->ops.serial_format = pl011_serial_format; + priv->ops.serial_irq_handler = pl011_serial_irq_handler; + priv->ops.serial_irq_set = pl011_serial_irq_set; + priv->ops.serial_putc = pl011_serial_putc; + priv->ops.serial_writable = pl011_serial_writable; + priv->ops.serial_getc = pl011_serial_getc; + priv->ops.serial_readable = pl011_serial_readable; +#if DEVICE_SERIAL_FC + priv->ops.serial_set_flow_control = pl011_serial_set_flow_control; +#endif + uart_data[priv->index].sw_rts.pin = NC; + uart_data[priv->index].sw_cts.pin = NC; + + /* Assign IRQ in advance and enable, all are masked anyways */ + NVIC_SetVector(irq_n, vector); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + NVIC_EnableIRQ(irq_n); + + /* dissable IRQ by this if needed: + NVIC_DisableIRQ(irq_n); + */ + +} + + +#endif // DEVICE_SERIAL diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_usi_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_usi_api.c new file mode 100644 index 0000000000..c1f3f1c28b --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/serial_usi_api.c @@ -0,0 +1,343 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ + +#if DEVICE_SERIAL + +// math.h required for floating point operations for baud rate calculation +#include +#include +#include +#include + +#include "device.h" +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PinNames.h" +#include "mbed_error.h" +#include "gpio_api.h" + +#include "s5js100.h" +#include "mbed_wait_api.h" +#include "mbed_thread.h" + +#define USI_PTR(ptr) ((S5JS100_USI_UART_TypeDef *)(ptr)) +static uart_irq_handler irq_handler[USI_MAX_PORTS]; +static uint32_t serial_irq_id[USI_MAX_PORTS] = {0}; + + + + +/****************** Internal code ************************/ +static inline void uart_irq(uint32_t intstatus, uint32_t index, + UARTName uart) +{ + + if (intstatus & (1 << 0)) { + (irq_handler[index])(serial_irq_id[index], RxIrq); + } else if (intstatus & (1 << 1)) { + // RTS Int + } else if (intstatus & (1 << 2)) { + (irq_handler[index])(serial_irq_id[index], TxIrq); + } else if (intstatus & (1 << 3)) { + // CTS Int + } else { + } + + USI_PTR(uart)->UINTP = intstatus; +} + + + + +static void uart0_irq() +{ + uart_irq(S5JS100_USI0_UART->UINTP & 0xF, 0, UART_0); +} + +static void uart1_irq() +{ + uart_irq(S5JS100_USI1_UART->UINTP & 0xF, 1, UART_1); +} + + +/*********************** API ******************************/ + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +static void usi_serial_baud(void *obj, int baudrate) +{ + struct serial_s *priv = (struct serial_s *)obj; + int32_t sclk = 0; + float div, frac; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + switch ((int)priv->uart) { + case UART_0: + /* UBRDIV and UFRACVAL */ + sclk = cal_clk_getrate(d1_usi0); + break; + + case UART_1: + /* UBRDIV and UFRACVAL */ + sclk = cal_clk_getrate(d1_usi1); + break; + + default: + MBED_ASSERT(false); + } + + + div = ((float)sclk / (float)(baudrate * 16)) - 1.0; + frac = (uint32_t)(((div - (int32_t)div) * 16)); + p_USI_UART->UBRDIV = (uint32_t)div; + p_USI_UART->UFRACVAL = (uint32_t)frac; +} + + +static void usi_serial_format(void *obj, int data_bits, + SerialParity parity, int stop_bits) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + uint32_t reg; + + switch (data_bits) { + case 5: + reg = UART_ULCON_DATABITS_5BITS; + break; + case 6: + reg = UART_ULCON_DATABITS_6BITS; + break; + case 7: + reg = UART_ULCON_DATABITS_7BITS; + break; + default: + reg = UART_ULCON_DATABITS_8BITS; + } + + switch (parity) { + case ParityNone: + reg |= UART_ULCON_PARITY_NONE; + break; + case ParityOdd: + reg |= UART_ULCON_PARITY_ODD; + break; + case ParityEven: + reg |= UART_ULCON_PARITY_EVEN; + break; + case ParityForced1: + reg |= UART_ULCON_PARITY_FORCE1; + break; + case ParityForced0: + reg |= UART_ULCON_PARITY_FORCE0; + break; + } + + if (stop_bits == 2) { + reg |= UART_ULCON_STOPBITS_2BITS; + } + + p_USI_UART->ULCON = reg; +} + + +static void usi_serial_irq_handler(void *obj, uart_irq_handler handler, uint32_t id) +{ + struct serial_s *priv = (struct serial_s *)obj; + + irq_handler[priv->index] = handler; + serial_irq_id[priv->index] = id; +} + + + +static void usi_serial_irq_set(void *obj, SerialIrq irq, uint32_t enable) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + + switch (irq) { + case RxIrq: + if (enable) { + p_USI_UART->UINTM &= ~(UART_UINTM_RXD_MASK); + } else { + p_USI_UART->UINTM |= UART_UINTM_RXD_MASK; + p_USI_UART->UINTP = UART_UINTP_RXD; + } + break; + case TxIrq: + if (enable) { + p_USI_UART->UINTM &= ~(UART_UINTM_TXD_MASK); + } else { + p_USI_UART->UINTM |= UART_UINTM_TXD_MASK; + p_USI_UART->UINTP = UART_UINTP_TXD; + } + break; + } +} + +static int usi_serial_writable(void *obj) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + + return !(p_USI_UART->UFSTAT & UART_UFSTAT_TX_FIFO_FULL); +} + + +static void usi_serial_putc(void *obj, int c) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + while (!serial_writable(obj)); + p_USI_UART->UTXH = c; +} + + + +static int usi_serial_readable(void *obj) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + return (p_USI_UART->UFSTAT & (UART_UFSTAT_RX_FIFO_COUNT_MASK | UART_UFSTAT_RX_FIFO_FULL)); +} + +static int usi_serial_getc(void *obj) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + int data; + while (!serial_readable(obj)); + data = p_USI_UART->URXH & 0xFF; + + return data; +} + +#if DEVICE_SERIAL_FC +static void usi_serial_set_flow_control(struct serial_s *obj, FlowControl type, + PinName rxflow, PinName txflow) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + // Checked used UART name (UART_1, UART_2, ...) + if (type == FlowControlRTSCTS) { + p_USI_UART->UMCON = UART_UMCON_RTS_TRIG_14BYTES | UART_UMCON_AFC_ENABLE; + } else { + p_USI_UART->UMCON = UART_UMCON_AFC_DISABLE; + } +} +#endif + +void usi_serial_init(void *obj, PinName tx, PinName rx) +{ + struct serial_s *priv = (struct serial_s *)obj; + S5JS100_USI_UART_TypeDef *p_USI_UART = USI_PTR(priv->uart); + + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + + + p_USI_UART->UINTM = 0xF; + p_USI_UART->UINTP = 0xF; + + switch ((int)priv->uart) { + case UART_0: + if (! USI_VERSION_UART(S5JS100_USI0_REG->VERSION)) { + /* UART NOT SUPPORTED */ + MBED_ASSERT(false); + } + + S5JS100_USI0_REG->CON = USI_CON_RST; + S5JS100_SYSCFG_USI0_CONF = USI_CONFIG_UART; + S5JS100_USI0_REG->CON &= ~USI_CON_RST; + + priv->index = USI0_PORT_ID; + priv->rx_fifo_depth = USI_RXFIFO(S5JS100_USI0_REG->FIFO_DEPTH); + priv->tx_fifo_depth = USI_TXFIFO(S5JS100_USI0_REG->FIFO_DEPTH); + + irq_n = S5JS100_IRQ_USI0; + vector = (uint32_t)&uart0_irq; + + break; + + case UART_1: + if (! USI_VERSION_UART(S5JS100_USI1_REG->VERSION)) { + /* UART NOT SUPPORTED */ + while (1); + } + + S5JS100_USI1_REG->CON = USI_CON_RST; + S5JS100_SYSCFG_USI1_CONF = USI_CONFIG_UART; + S5JS100_USI1_REG->CON &= ~USI_CON_RST; + + priv->index = USI1_PORT_ID; + priv-> rx_fifo_depth = USI_RXFIFO(S5JS100_USI1_REG->FIFO_DEPTH); + priv-> tx_fifo_depth = USI_TXFIFO(S5JS100_USI1_REG->FIFO_DEPTH); + irq_n = S5JS100_IRQ_USI1; + vector = (uint32_t)&uart1_irq; + + break; + } + + + + // Disable all interrupts and clear pendings + p_USI_UART->UINTM = UART_UINTM_MODEM_MASK | UART_UINTM_TXD_MASK | + UART_UINTM_RXD_MASK | UART_UINTM_ERROR_MASK; + p_USI_UART->UINTP = UART_UINTP_MODEM | UART_UINTP_TXD | + UART_UINTP_ERROR | UART_UINTP_RXD; + + // reset FIFO and set interrupt trigger level + p_USI_UART->UFCON = UART_UFCON_TX_FIFO_TRIG_14BYTES | UART_UFCON_RX_FIFO_TRIG_14BYTES | + UART_UFCON_TX_FIFO_RESET | UART_UFCON_RX_FIFO_RESET | + UART_UFCON_FIFO_ENABLE ; + + //wait_ms(10); + thread_sleep_for(10); + + //Enable TX/RX fifo int/poll mode with RX timeout of 32 bits duration + p_USI_UART->UCON = UART_UCON_RX_TOUT_32FRAMES | UART_UCON_RX_TOUTINT_ENABLE | + UART_UCON_TX_INTTYPE_LEVEL | UART_UCON_RX_INTTYPE_LEVEL | + UART_UCON_TX_MODE_IRQPOLL | UART_UCON_RX_MODE_IRQPOLL; + + priv->ops.serial_baud = usi_serial_baud; + priv->ops.serial_format = usi_serial_format; + priv->ops.serial_irq_handler = usi_serial_irq_handler; + priv->ops.serial_irq_set = usi_serial_irq_set; + priv->ops.serial_putc = usi_serial_putc; + priv->ops.serial_writable = usi_serial_writable; + priv->ops.serial_getc = usi_serial_getc; + priv->ops.serial_readable = usi_serial_readable; + +#if DEVICE_SERIAL_FC + priv->ops.serial_set_flow_control = usi_serial_set_flow_control; +#endif + /* Assign IRQ in advance and enable, all are masked anyways */ + NVIC_SetVector(irq_n, vector); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + NVIC_EnableIRQ(irq_n); + + /* dissable IRQ by this if needed: + NVIC_DisableIRQ(irq_n); + */ +} + + +#endif // DEVICE_SERIAL diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/sleep.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/sleep.c new file mode 100644 index 0000000000..688da9db99 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/sleep.c @@ -0,0 +1,160 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ +#if DEVICE_SLEEP + +#include +#include +#include "sleep_api.h" +#include "cmsis.h" +#include "gpio_api.h" +#include "mbed_power_mgmt.h" +#include "mbed_critical.h" +#include "rtos_idle.h" + +int nbsleep_req = 0; +int external_pin = 0; +static int initialize_policy = 0; +static int disable_poweroffbycp = 1; + +static inline void hw_delay_us(unsigned int value) +{ + volatile unsigned i, j; + for (i = 0; i < (value * 2); i++) { + for (j = 0; j < 100; j++); + } +} + +int s5js100_idle_sicd(void) +{ + if (getreg32(0x85023090) & (0x1 << 1)) { + /* send CP to ready status */ + modifyreg32(0x85023090, (0x1 << 2), (0x1 << 2)); + modifyreg32(0x85026100, 0x2, 0x0); + + pmu_short_sleep(); //go to sleep + + modifyreg32(0x85026100, 0x2, 0x2); + + /* wait for mbox */ + while ((getreg32(0x85023090) & (0x1 << 1))) { + hw_delay_us(10); + putreg32(0x2, 0x85023020); + putreg32(0x2, 0x8502301C); + }; + + /* release short sleep status */ + modifyreg32(0x85023090, (0x1 << 2), (0x0 << 2)); + return 1; + } else { + asm("wfi"); + } + + return 0; +} + +static void s5js100_idle_hook(void) +{ + core_util_critical_section_enter(); + sleep(); + core_util_critical_section_exit(); +} + +static void set_sleep_policy(void) +{ + rtos_attach_idle_hook(&s5js100_idle_hook); + initialize_policy = 1; +} + +void config_poweroffbycp(int enable) +{ + disable_poweroffbycp = (enable == 0) ? 1 : 0; +} + +static int change_cp_pwr_lock(int lock) +{ + static int prev_lock = 1; + int i; + + lock &= 0x1; + + if (lock == prev_lock) { + return 0; + } + + if (lock == 0) { + modifyreg32(0x85023088, 0x1, 0x0); + prev_lock = 0; + return 0; + } + + modifyreg32(0x85023088, 0x1, 0x1); + prev_lock = 1; + + if (prev_lock == 0) { + for (i = 0; i < 1000; i++) + if (s5js100_idle_sicd()) { + return 1; + } + } + + return 0; +} + + +void hal_sleep(void) +{ + if (initialize_policy == 0) { + set_sleep_policy(); + } + + if (!strcmp(get_env("SLEEP"), "ON") && disable_poweroffbycp != 1) { + hal_deepsleep(); + return; + } + + modifyreg32(0x85026100, 0x2, 0x2); + + if (!change_cp_pwr_lock(1)) { + asm("wfi"); + } + + modifyreg32(0x85026100, 0x2, 0x0); +} + +void hal_deepsleep(void) +{ + int cp_pwr_lock = external_pin | disable_poweroffbycp; + + if (nbsleep_req) { + pmu_nb_sleep(); + } + + modifyreg32(0x85026100, 0x2, 0x2); + + if (change_cp_pwr_lock(cp_pwr_lock)) { + goto out; + } + + s5js100_idle_sicd(); + +out: + modifyreg32(0x85026100, 0x2, 0x2); +} + +#endif // DEVICE_SLEEP diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_api.c new file mode 100644 index 0000000000..081b4d3b74 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_api.c @@ -0,0 +1,553 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#if DEVICE_SPI + +#include + +#include "spi_api.h" +#include "spi_def.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "mbed_wait_api.h" + +/* + * Driver private data structure that should not be shared by multiple + * instances of the driver (same driver for multiple instances of the IP) + */ +typedef struct { + uint32_t size; /* size of an SPI frame in bits: can be 8 or 16 */ +} private_spi_t; + +int s5js100_configgpio(uint32_t cfgset); + +static const PinMap PinMap_SPI_SCLK[] = { + {SPI0_CLK, SPI_0, 0}, + {SPI1_CLK, SPI_1, 0}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {SPI0_MOSI, SPI_0, 0}, + {SPI1_MOSI, SPI_1, 0}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {SPI0_MISO, SPI_0, 0}, + {SPI1_MISO, SPI_1, 0}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {SPI0_CSN, SPI_0, 0}, + {SPI1_CSN, SPI_1, 0}, + {NC, NC, 0} +}; + +/* + * Retrieve the private data of the instance related to a given IP + */ +private_spi_t *get_spi_private(spi_t *obj) +{ + static private_spi_t data0, data1; + /* + * Select which instance to give using the base + * address of registers + */ + switch ((intptr_t)obj->spi) { + case SPI0_BASE: + return &data0; + case SPI1_BASE: + return &data1; + default: + error("SPI driver private data structure not found for this registers base address"); + return (void *)0; + } +} +#ifndef CONFIG_EXAMPLES_SPI_BUS_NUM +#define CONFIG_EXAMPLES_SPI_BUS_NUM 0 +#endif + +static inline uint32_t ssp_getreg(spi_t *priv, uint8_t offset) +{ + return getreg32(priv->base + (uint32_t) offset); +} + +static inline void ssp_putreg(spi_t *priv, uint8_t offset, uint32_t value) +{ + putreg32(value, priv->base + (uint32_t) offset); +} + +void ssp_setmode(spi_t *priv, enum spi_mode_e mode) +{ + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) { + /* Yes... Set CR0 appropriately */ + + regval = ssp_getreg(priv, S5JS100_SSP_CR0_OFFSET); + regval &= ~(SSP_CR0_CPOL | SSP_CR0_CPHA); + + switch (mode) { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SSP_CR0_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SSP_CR0_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SSP_CR0_CPOL | SSP_CR0_CPHA); + break; + + default: + error("ERROR: Bad mode: %d\n", mode); + return; + } + + ssp_putreg(priv, S5JS100_SSP_CR0_OFFSET, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +static void ssp_setbits(spi_t *priv, int nbits) +{ + uint32_t regval; + + /* Has the number of bits changed? */ + if (priv == NULL || nbits <= 3 || nbits >= 17) { + error("SPI setbit error"); + } + + if ((uint32_t)nbits != priv->nbits) { + /* Yes... Set CR1 appropriately */ + + regval = ssp_getreg(priv, S5JS100_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_DSS_MASK; + regval |= ((nbits - 1) << SSP_CR0_DSS_SHIFT); + ssp_putreg(priv, S5JS100_SSP_CR0_OFFSET, regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +static uint32_t ssp_setfrequency(spi_t *priv, uint32_t frequency) +{ + uint32_t cpsdvsr; + uint32_t scr; + uint32_t regval; + uint32_t actual; + + /* Check if the requested frequency is the same as the frequency selection */ + + if (!(priv && frequency <= SSP_CLOCK / 2)) { + error("SSP Frequency error"); + } + + if (priv->frequency == frequency) { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* Set clock source value */ + cal_clk_setrate(priv->freqid, (unsigned long)SSP_CLOCK); + + /* The SSP bit frequency is given by: + * + * frequency = SSP_CLOCK / (CPSDVSR * (SCR+1)). + * + * Let's try for a solution with the smallest value of SCR. NOTES: + * (1) In the calculations below, the value of the variable 'scr' is + * (SCR+1) in the above equation. (2) On slower s5jxx parts, SCR + * will probably always be zero. + */ + + for (scr = 1; scr <= 256; scr++) { + /* CPSDVSR = SSP_CLOCK / (SCR + 1) / frequency */ + + cpsdvsr = (SSP_CLOCK / scr) / frequency; + + /* Break out on the first solution we find with the smallest value + * of SCR and with CPSDVSR within the maximum range or 254. + */ + + if (cpsdvsr < 255) { + break; + } + } + + if (!(scr <= 256 && cpsdvsr <= 255)) { + error("SSP Frequency error"); + } + + /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */ + + if (cpsdvsr < 2) { + /* Clip to the minimum value. */ + + cpsdvsr = 2; + } else if (cpsdvsr > 254) { + /* This should never happen */ + + cpsdvsr = 254; + } + + /* Force even */ + + cpsdvsr = (cpsdvsr + 1) & ~1; + + /* Save the new CPSDVSR and SCR values */ + + ssp_putreg(priv, S5JS100_SSP_CPSR_OFFSET, cpsdvsr); + + regval = ssp_getreg(priv, S5JS100_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_SCR_MASK; + regval |= ((scr - 1) << SSP_CR0_SCR_SHIFT); + ssp_putreg(priv, S5JS100_SSP_CR0_OFFSET, regval); + + /* Calculate the new actual */ + + actual = (SSP_CLOCK / cpsdvsr) / scr; + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + return actual; +} + +static void ssp_exchange(spi_t *priv, const void *txbuffer, void *rxbuffer, size_t nwords) +{ + size_t sent = 0; + size_t received = 0; + int word_length; + + SSP_Typedef *pSSPRegs; + pSSPRegs = (SSP_Typedef *) priv->base; + + word_length = pSSPRegs->S5JS100_SSP_CR0_reg & SSP_CR0_DSS_MASK; + + /* TX/RX */ + if ((rxbuffer == NULL) && (txbuffer == NULL)) { + while (received < nwords) { + if (sent < nwords) + if (SSP_SR_TNF_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + pSSPRegs->S5JS100_SSP_DR_reg = 0; + sent++; + } + + if (SSP_SR_RNE_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + received++; + } + } + return; + } + + if (rxbuffer == NULL) { + while (received < nwords) { + if (sent < nwords) + if (SSP_SR_TNF_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + if (word_length > SSP_CR0_DSS_8BIT) { + pSSPRegs->S5JS100_SSP_DR_reg = ((uint16_t *) txbuffer)[sent++]; + } else { + pSSPRegs->S5JS100_SSP_DR_reg = ((uint8_t *) txbuffer)[sent++]; + } + } + + if (SSP_SR_RNE_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + received++; + } + } + return; + } + + if (txbuffer == NULL) { + while (received < nwords) { + if (sent < nwords) + if (SSP_SR_TNF_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + if (word_length > SSP_CR0_DSS_8BIT) { + pSSPRegs->S5JS100_SSP_DR_reg = ((uint16_t *) rxbuffer)[sent++]; + } else { + pSSPRegs->S5JS100_SSP_DR_reg = ((uint8_t *) rxbuffer)[sent++]; + } + } + + if (SSP_SR_RNE_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + if (word_length > SSP_CR0_DSS_8BIT) { + ((uint16_t *) rxbuffer)[received++] = pSSPRegs->S5JS100_SSP_DR_reg; + } else { + ((uint8_t *) rxbuffer)[received++] = pSSPRegs->S5JS100_SSP_DR_reg; + } + } + + } + return; + } + + while (received < nwords) { + if (sent < nwords) + if (SSP_SR_TFE_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + if (word_length > SSP_CR0_DSS_8BIT) { + pSSPRegs->S5JS100_SSP_DR_reg = ((uint16_t *) txbuffer)[sent++]; + } else { + pSSPRegs->S5JS100_SSP_DR_reg = ((uint8_t *) txbuffer)[sent++]; + } + } + + if (SSP_SR_RNE_CHECK(pSSPRegs->S5JS100_SSP_SR_reg)) { + if (word_length > SSP_CR0_DSS_8BIT) { + ((uint16_t *) rxbuffer)[received++] = pSSPRegs->S5JS100_SSP_DR_reg; + } else { + ((uint8_t *) rxbuffer)[received++] = pSSPRegs->S5JS100_SSP_DR_reg; + } + } + } +} + + +void ssp_select(spi_t *priv, int selected) +{ + SSP_Typedef *pSSPRegs; + pSSPRegs = (SSP_Typedef *) priv->base; + + if (selected) { + pSSPRegs->S5JS100_SSP_CR1_reg &= ~SSP_CR1_CS; + } else { + pSSPRegs->S5JS100_SSP_CR1_reg |= SSP_CR1_CS; + } +} +void spi_free(spi_t *obj) +{ +} + +void spi_select(spi_t *obj, int selected) +{ +#if 0 + SPI_TypeDef *pSPIRegs; + pSPIRegs = obj->spi; + + unsigned int cs_reg; + cs_reg = getreg32(&pSPIRegs->CS_REG); + cs_reg |= CS_REG_nSS_INACTIVE; + + if (selected == 1) { + cs_reg &= ~CS_REG_nSS_INACTIVE; + } + + putreg32(cs_reg, &pSPIRegs->CS_REG); +#endif + ssp_select(obj, selected); +} + + +void spi_setmode(spi_t *obj, int mode) +{ + ssp_setmode(obj, mode); +} + +void spi_setbits(spi_t *obj, int nbits) +{ + ssp_setbits(obj, nbits); +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) +{ + spi_setmode(obj, mode); + spi_setbits(obj, bits); +} + +void spi_frequency(spi_t *obj, int hz) +{ + //cal_clk_setrate(obj->freqid, (unsigned long)hz); + ssp_setfrequency(obj, (uint32_t)hz); +} + + +static void spi_exchange(spi_t *obj, const void *txbuffer, void *rxbuffer, unsigned int nwords) +{ + ssp_exchange(obj, txbuffer, rxbuffer, nwords); +} + +int spi_master_write(spi_t *obj, int value) +{ +//// private_spi_t *private_spi = get_spi_private(obj); + unsigned char txbyte; + unsigned char rxbyte; + + txbyte = (unsigned char)value; + rxbyte = (unsigned char)0; + + spi_select(obj, 1); + spi_exchange(obj, &txbyte, &rxbyte, 1); + spi_select(obj, 0); + + return (unsigned int)rxbyte; +} + +int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, + char *rx_buffer, int rx_length, char write_fill) +{ + int total = (tx_length > rx_length) ? tx_length : rx_length; + + spi_select(obj, 1); + spi_exchange(obj, tx_buffer, rx_buffer, tx_length); + spi_select(obj, 0); + + return total; +} + +uint8_t spi_get_module(spi_t *obj) +{ + return 0; +} + +int spi_busy(spi_t *obj) +{ + return 0; +} + + +void spi_init(spi_t *obj, PinName mosi, + PinName miso, PinName sclk, PinName ssel) +{ + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + obj->spi = (SPI_TypeDef *)pinmap_merge(spi_data, spi_cntl); + if ((int)obj->spi == NC) { + error("SPI pinout mapping failed"); + } + obj->base = SPI0_BASE; + + uint32_t regval; + uint32_t i; + + s5js100_configgpio(sclk); + s5js100_configgpio(ssel); + s5js100_configgpio(miso); + s5js100_configgpio(mosi); + + switch (CONFIG_EXAMPLES_SPI_BUS_NUM) { + case 0 : + obj->freqid = d1_spi0; + break; + default : + error("SPI Bus select error"); + break; + } + /* Configure 8-bit SPI mode */ + ssp_putreg(obj, S5JS100_SSP_CR0_OFFSET, SSP_CR0_DSS_8BIT | SSP_CR0_FRF_SPI); + + /* Disable the SSP and all interrupts (we'll poll for all data) */ + ssp_putreg(obj, S5JS100_SSP_CR1_OFFSET, 0); + ssp_putreg(obj, S5JS100_SSP_IMSC_OFFSET, 0); + + obj->frequency = 0; + obj->nbits = 8; + obj->mode = SPIDEV_MODE0; + + /* Set the initial SSP configuration */ + spi_setmode(obj, SPIDEV_MODE0); + spi_setbits(obj, 8); + spi_frequency(obj, 1000000); + + regval = ssp_getreg(obj, S5JS100_SSP_CR1_OFFSET); + + ssp_putreg(obj, S5JS100_SSP_CR1_OFFSET, regval | SSP_CR1_SSE | SSP_CR1_CSE); + + for (i = 0; i < S5JS100_SSP_FIFOSZ; i++) { + (void)ssp_getreg(obj, S5JS100_SSP_DR_OFFSET); + } +} + +const PinMap *spi_master_mosi_pinmap() +{ + return PinMap_SPI_MOSI; +} + +const PinMap *spi_master_miso_pinmap() +{ + return PinMap_SPI_MISO; +} + +const PinMap *spi_master_clk_pinmap() +{ + return PinMap_SPI_SCLK; +} + +const PinMap *spi_master_cs_pinmap() +{ + return PinMap_SPI_SSEL; +} + +const PinMap *spi_slave_mosi_pinmap() +{ + return PinMap_SPI_MOSI; +} + +const PinMap *spi_slave_miso_pinmap() +{ + return PinMap_SPI_MISO; +} + +const PinMap *spi_slave_clk_pinmap() +{ + return PinMap_SPI_SCLK; +} + +const PinMap *spi_slave_cs_pinmap() +{ + return PinMap_SPI_SSEL; +} + +#endif // DEVICE_SPI diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_def.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_def.h new file mode 100644 index 0000000000..ffa4e0ec4e --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/spi_def.h @@ -0,0 +1,287 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/* + * SSP interface Support + * ===================== + */ + +#ifndef MBED_SPI_DEF_H +#define MBED_SPI_DEF_H + +#include /* standard types definitions */ + +#define Module_ID 0x00090108 + +typedef struct beetle_spi { + volatile unsigned int CONFIG; /* 0x00 RW Configuration Register */ + volatile unsigned int CLK_CFG; /* 0x04 */ + volatile unsigned int MODE_CONFIG; /* 0x08 RW SPI FIFO control Register */ + volatile unsigned int CS_REG; /* 0x0C RW Slave Selection Register */ + volatile unsigned int IRQ_ENABLE; /* 0x10 RO Interrupt Enable Register*/ + volatile unsigned int SPI_STATUS; /* 0x14 RW SPI Status Register */ + volatile unsigned int SPI_TX_DATA; /* 0x18 WO Transmit Data Register */ + volatile unsigned int SPI_RX_DATA; /* 0x1C RO Receive Data Register */ + volatile unsigned int IRQ_DISABLE; /* 0x WO Interrupt Disable Register */ + volatile unsigned int SPI_ENABLE; /* 0x14 RW SPI Enable Register */ + volatile unsigned int TX_THRESHOLD; /* 0x28 RW TX Threshold Register */ + volatile unsigned int RX_THRESHOLD; /* 0x2C RW RX Threshold Register */ +} SPI_TypeDef; + +typedef struct _SSP_SFR { + uint32_t volatile S5JS100_SSP_CR0_reg; /* 0x0000 Control Register 0 */ + uint32_t volatile S5JS100_SSP_CR1_reg; /* 0x0004 Control Register 1 */ + uint32_t volatile S5JS100_SSP_DR_reg; /* 0x0008 Data Register */ + uint32_t volatile S5JS100_SSP_SR_reg; /* 0x000c Status Register */ + uint32_t volatile S5JS100_SSP_CPSR_reg; /* 0x0010 Clock Prescale Register */ + uint32_t volatile S5JS100_SSP_IMSC_reg; /* 0x0014 Interrupt Mask Set and Clear Register */ + uint32_t volatile S5JS100_SSP_RIS_reg; /* 0x0018 Raw Interrupt Status Register */ + uint32_t volatile S5JS100_SSP_MIS_reg; /* 0x001c Masked Interrupt Status Register */ + uint32_t volatile S5JS100_SSP_ICR_reg; /* 0x0020 Interrupt Clear Register */ + uint32_t volatile S5JS100_SSP_DMACR_reg;/* 0x0024 DMA Control Register */ +} SSP_Typedef; + +#define SPI0_BASE (0x83016000) /* Shield Header SPI Base Address */ +#define SPI1_BASE (0x83015000) /* ADC SPI Base Address */ + +#define SHIELD_SPI ((SPI_TypeDef *) SPI0_BASE ) +#define ADC_SPI ((SPI_TypeDef *) SPI1_BASE ) + +/* Configuration Register Bit Masks */ +#define CONFIG_MSEL 0x00001 // Bit [00] MSEL Mode Select +#define CONFIG_CPOL 0x00002 // Bit [01] CPOL External Clock Edge +#define CONFIG_CPHA 0x00004 // Bit [02] CPHA Clock Phase +#define CONFIG_MBRD 0x00038 // Bits [05:03] MBRD Master Baud Rate Divisor (2 to 256) +#define CONFIG_MBRD_0 0x00008 +#define CONFIG_MBRD_1 0x00010 +#define CONFIG_MBRD_2 0x00020 +#define CONFIG_MBRD_SHIFT 3 +#define CONFIG_TWS 0x000C0 // Bits [07:06] TWS Transfer Word Size +#define CONFIG_TWS_0 0x00000 +#define CONFIG_TWS_1 0x00040 +#define CONFIG_MRCS 0x00100 // Bit [08] MRCS Reference Clock Select +#define CONFIG_PSD 0x00200 // Bit [09] PSD Peripheral Select Decode +#define CONFIG_PCSL 0x03C00 // Bits [13:10] PCSL Peripheral Chip Select Lines (master mode only) +#define CONFIG_MCSE 0x04000 // Bit [14] MCSE Manual Chip Select Enable +#define CONFIG_MSE 0x08000 // Bit [15] MSE Manual Start Enable +#define CONFIG_MSC 0x10000 // Bit [16] MSC Manual Start Command +#define CONFIG_MFGE 0x20000 // Bit [17] MFGE Mode Fail Generation Enable +#define CONFIG_SPSE 0x40000 // Bit [18] SPSE Sample Point Shift Enable + +/* Interrupt Status Register Bit Masks */ +#define IRQ_STATUS_ROF 0x01 // Bit [00] ROF RX FIFO Overflow +#define IRQ_STATUS_MF 0x02 // Bit [01] MF Mode Fail +#define IRQ_STATUS_TNF 0x04 // Bit [02] TNF TX FIFO Not Full (current FIFO status) +#define IRQ_STATUS_TF 0x08 // Bit [03] TF TX FIFO Full (current FIFO status) +#define IRQ_STATUS_RNE 0x10 // Bit [04] RNE RX FIFO Not Empty (current FIFO status) +#define IRQ_STATUS_RF 0x20 // Bit [05] RF RX FIFO Full (current FIFO status) +#define IRQ_STATUS_TUF 0x40 // Bit [06] TUF TX FIFO Underflow + +/* Interrupt Enable Register Bit Masks */ +#define IRQ_ENABLE_ROFE 0x01 // Bit [00] ROFE RX FIFO Overflow Enable +#define IRQ_ENABLE_MFE 0x02 // Bit [01] MFE Mode Fail Enable +#define IRQ_ENABLE_TNFE 0x04 // Bit [02] TNFE TX FIFO Not Full Enable +#define IRQ_ENABLE_TFE 0x08 // Bit [03] TFE TX FIFO Full Enable +#define IRQ_ENABLE_RNEE 0x10 // Bit [04] RNEE RX FIFO Not Empty Enable +#define IRQ_ENABLE_RFE 0x20 // Bit [05] RFE RX FIFO Full Enable +#define IRQ_ENABLE_TUFE 0x40 // Bit [06] TUFE TX FIFO Underflow Enable + +/* Interrupt Disable Register Bit Masks */ +#define IRQ_DISABLE_ROFD 0x01 // Bit [00] ROFD RX FIFO Overflow Disable +#define IRQ_DISABLE_MFD 0x02 // Bit [01] MFD Mode Fail Disable +#define IRQ_DISABLE_TNFD 0x04 // Bit [02] TNFD TX FIFO Not Full Disable +#define IRQ_DISABLE_TFD 0x08 // Bit [03] TFD TX FIFO Full Disable +#define IRQ_DISABLE_RNED 0x10 // Bit [04] RNED RX FIFO Not Empty Disable +#define IRQ_DISABLE_RFD 0x20 // Bit [05] RFD RX FIFO Full Disable +#define IRQ_DISABLE_TUFD 0x40 // Bit [06] TUFD TX FIFO Underflow Disable + +/* Interrupt Mask Register Bit Masks */ +#define IRQ_MASK_ROFM 0x01 // Bit [00] ROFM RX FIFO Overflow Mask +#define IRQ_MASK_MFM 0x02 // Bit [01] MFM Mode Fail Mask +#define IRQ_MASK_TNFM 0x04 // Bit [02] TNFM TX FIFO Not Full Mask +#define IRQ_MASK_TFM 0x08 // Bit [03] TFM TX FIFO Full Mask +#define IRQ_MASK_RNEM 0x10 // Bit [04] RNEM RX FIFO Not Empty Mask +#define IRQ_MASK_RFM 0x20 // Bit [05] RFM RX FIFO Full Mask +#define IRQ_MASK_TUFM 0x40 // Bit [06] TUFM TX FIFO Underflow Mask + +/* SPI Enable Register Bit Masks */ +#define SPI_ENABLE_SPIE 0x01 // Bit [00] SPIE SPI Enable + +/* Delay Register Bit Masks */ +#define DELAY_D_INIT 0x000000FF // Bits [07:00] D_INIT Delay Init +#define DELAY_D_AFTER 0x0000FF00 // Bits [15:08] D_AFTER Delay After +#define DELAY_D_BTWN 0x00FF0000 // Bits [23:16] D_BTWN Delay Between +#define DELAY_D_NSS 0xFF000000 // Bits [31:24] D_NSS Delay NSS + +/* Transmit Data Register Bit Masks */ +#define TX_DATA_TDATA 0xFF + +/* Receive Data Register Bit Masks */ +#define RX_DATA_RDATA 0xFF + +/* Slave Idle Count Register Bit Masks */ +#define SLAVE_IDLE_COUNT_SICNT 0xFF // Bits [07:00] SICNT Slave Idle Count + +/* TX Threshold Register Bit Masks */ +#define TX_THRESHOLD_TTRSH 0x07 // Bits [N:00] TTRSH TX Threshold + +/* RX Threshold Register Bit Masks */ +#define RX_THRESHOLD_RTRSH 0x07 // Bits [N:00] RTRSH RX Threshold + +#define CH_CFG_TX_CH_ON (1 << 0) +#define CH_CFG_TX_CH_OFF (0 << 0) +#define CH_CFG_RX_CH_ON (1 << 1) +#define CH_CFG_RX_CH_OFF (0 << 1) +#define CH_CFG_MODE_MASK (3 << 2) +#define CH_CFG_MODE(x) ((x & 3) << 2) +#define CH_CFG_SLAVE (1 << 4) +#define CH_CFG_MASTER (0 << 4) +#define CH_CFG_FIFO_FLUSH (1 << 5) +#define CH_CFG_FIFO_FLUSH_OFF (0 << 5) +#define CH_CFG_HIGH_SPEED_EN (1 << 6) +#define CH_CFG_HIGH_SPEED_DIS (0 << 6) + +#define MODE_CFG_DMA_SINGLE (0 << 0) +#define MODE_CFG_DMA_4BURST (1 << 0) +#define MODE_CFG_DMA_TX_ON (1 << 1) +#define MODE_CFG_DMA_TX_OFF (0 << 1) +#define MODE_CFG_DMA_RX_ON (1 << 2) +#define MODE_CFG_DMA_RX_OFF (0 << 2) +#define MODE_CFG_TX_RDY_LVL(x) ((x & 0x3F) << 5) +#define MODE_CFG_RX_RDY_LVL(x) ((x & 0x3F) << 11) +#define MODE_CFG_BUS_WDT_MASK (3 << 17) +#define MODE_CFG_BUS_WIDTH_8 (0 << 17) +#define MODE_CFG_BUS_WIDTH_16 (1 << 17) +#define MODE_CFG_BUS_WIDTH_32 (2 << 17) +#define GET_MODE_CFG_BUSW(x) (1 << ((x & MODE_CFG_BUS_WDT_MASK) >> 17)) +#define MODE_CFG_TRLNG_CNT(x) ((x & 0x3FF) << 19) +#define MODE_CFG_CH_WDT_MASK (3 << 29) +#define MODE_CFG_CH_WIDTH_8 (0 << 29) +#define MODE_CFG_CH_WIDTH_16 (1 << 29) +#define MODE_CFG_CH_WIDTH_32 (2 << 29) + +#define CS_REG_nSS_ACTIVE (0 << 0) +#define CS_REG_nSS_INACTIVE (1 << 0) +#define CS_REG_nSS_AUTO (1 << 1) +#define CS_REG_nSS_MANUAL (0 << 1) +#define CS_REG_nSS_TIME_CNT(x) ((x & 0x3F) << 1) + +#define INT_MASK_TRAILING (1 << 6) +#define INT_MASK_RX_OVERRUN (1 << 5) +#define INT_MASK_RX_UNDERRUN (1 << 4) +#define INT_MASK_TX_OVERRUN (1 << 3) +#define INT_MASK_TX_UNDERRUN (1 << 2) +#define INT_MASK_RX_FIFO_RDY (1 << 1) +#define INT_MASK_TX_FIFO_RDY (1 << 0) + +#define SPI_STAT_TX_FIFO_RDY(x) ((x >> 0) & 1) +#define SPI_STAT_RX_FIFO_RDY(x) ((x >> 1) & 1) +#define SPI_STAT_TX_UNDERRUN(x) ((x >> 2) & 1) +#define SPI_STAT_TX_OVERRUN(x) ((x >> 3) & 1) +#define SPI_STAT_RX_UNDERRUN(x) ((x >> 4) & 1) +#define SPI_STAT_RX_OVERRUN(x) ((x >> 5) & 1) +#define SPI_STAT_TX_FIFO_LVL(x) ((x >> 6) & 0x1FF) +#define SPI_STAT_RX_FIFO_LVL(x) ((x >> 15) & 0x1FF) +#define SPI_STAT_TRAILING_BYTE(x) ((x >> 24) & 1) +#define SPI_STAT_TX_DONE(x) ((x >> 25) & 1) + +enum spi_mode_e { + SPIDEV_MODE0 = 0, /**< CPOL=0 CHPHA=0 */ + SPIDEV_MODE1, /**< CPOL=0 CHPHA=1 */ + SPIDEV_MODE2, /**< CPOL=1 CHPHA=0 */ + SPIDEV_MODE3 /**< CPOL=1 CHPHA=1 */ +}; + + +/* SSP *******************************************************************************************/ + +#define S5JS100_SSP_FIFOSZ (8) +#define SSP_CLOCK (200000000) /* SSP input frequency */ + +/* Register offsets *****************************************************************/ + +#define S5JS100_SSP_CR0_OFFSET (0x0000) /* Control Register 0 */ +#define S5JS100_SSP_CR1_OFFSET (0x0004) /* Control Register 1 */ +#define S5JS100_SSP_DR_OFFSET (0x0008) /* Data Register */ +#define S5JS100_SSP_SR_OFFSET (0x000c) /* Status Register */ +#define S5JS100_SSP_CPSR_OFFSET (0x0010) /* Clock Prescale Register */ +#define S5JS100_SSP_IMSC_OFFSET (0x0014) /* Interrupt Mask Set and Clear Register */ +#define S5JS100_SSP_RIS_OFFSET (0x0018) /* Raw Interrupt Status Register */ +#define S5JS100_SSP_MIS_OFFSET (0x001c) /* Masked Interrupt Status Register */ +#define S5JS100_SSP_ICR_OFFSET (0x0020) /* Interrupt Clear Register */ +#define S5JS100_SSP_DMACR_OFFSET (0x0024) /* DMA Control Register */ + +/* Register bit definitions *********************************************************/ +/* Control Register 0 */ + +#define SSP_CR0_DSS_SHIFT (0) /* Bits 0-3: DSS Data Size Select */ +#define SSP_CR0_DSS_MASK (15 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_4BIT (3 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_5BIT (4 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_6BIT (5 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_7BIT (6 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_8BIT (7 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_9BIT (8 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_10BIT (9 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_11BIT (10 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_12BIT (11 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_13BIT (12 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_14BIT (13 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_15BIT (14 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_DSS_16BIT (15 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_FRF_SHIFT (4) /* Bits 4-5: FRF Frame Format */ +#define SSP_CR0_FRF_MASK (3 << SSP_CR0_FRF_SHIFT) +#define SSP_CR0_FRF_SPI (0 << SSP_CR0_FRF_SHIFT) +#define SSP_CR0_FRF_TI (1 << SSP_CR0_FRF_SHIFT) +#define SSP_CR0_FRF_UWIRE (2 << SSP_CR0_FRF_SHIFT) +#define SSP_CR0_CPOL (1 << 6) /* Bit 6: Clock Out Polarity */ +#define SSP_CR0_CPHA (1 << 7) /* Bit 7: Clock Out Phase */ +#define SSP_CR0_SCR_SHIFT (8) /* Bits 8-15: Serial Clock Rate */ +#define SSP_CR0_SCR_MASK (0xff << SSP_CR0_SCR_SHIFT) +/* Bits 8-31: Reserved */ + +#define SSP_CR1_LBM (1 << 0) /* Bit 0: Loop Back Mode */ +#define SSP_CR1_SSE (1 << 1) /* Bit 1: SSP Enable */ +#define SSP_CR1_MS (1 << 2) /* Bit 2: Master/Slave Mode */ +#define SSP_CR1_SOD (1 << 3) /* Bit 3: Slave Output Disable */ +#define SSP_CR1_CSE (1 << 4) /* Bit 4: User CS enable */ +#define SSP_CR1_CS (1 << 5) /* Bit 5: User CS control */ +/* Bits 6-31: Reserved */ +/* Data Register */ + +#define SSP_DR_MASK (0xffff) /* Bits 0-15: Data */ +/* Bits 16-31: Reserved */ +/* Status Register */ + +#define SSP_SR_TFE (1 << 0) /* Bit 0: Transmit FIFO Empty */ +#define SSP_SR_TNF (1 << 1) /* Bit 1: Transmit FIFO Not Full */ +#define SSP_SR_RNE (1 << 2) /* Bit 2: Receive FIFO Not Empty */ +#define SSP_SR_RFF (1 << 3) /* Bit 3: Receive FIFO Full */ +#define SSP_SR_BSY (1 << 4) /* Bit 4: Busy */ + +#define SSP_SR_TFE_CHECK(x) ((x) & SSP_SR_TFE) /* Bit 0: Transmit FIFO Empty */ +#define SSP_SR_TNF_CHECK(x) ((x) & SSP_SR_TNF) /* Bit 1: Transmit FIFO Not Full */ +#define SSP_SR_RNE_CHECK(x) ((x) & SSP_SR_RNE) /* Bit 2: Receive FIFO Not Empty */ +#define SSP_SR_RFF_CHECK(x) ((x) & SSP_SR_RFF) /* Bit 3: Receive FIFO Full */ +#define SSP_SR_BSY_CHECK(x) ((x) & SSP_SR_BSY) /* Bit 4: Busy */ +/* Bits 5-31: Reserved */ +/* Clock Prescale Register */ + + +#endif diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.c new file mode 100644 index 0000000000..95902c3112 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +#if DEVICE_USTICKER + +#include +#include "cmsis.h" +#include "us_ticker_api.h" +#include "us_ticker.h" +#include "PeripheralNames.h" + +#define TIMER_TARGET_COUNT_DEFAULT 0xFFFFFFFF + +volatile uint32_t us_ticker_initialized = 0; +volatile uint32_t us_user_intset; +volatile uint32_t g_us_last_return = 0; + +void us_ticker_enable_interrupt(void); +void us_ticker_disable_interrupt(void); + +const ticker_info_t *us_ticker_get_info() +{ + static const ticker_info_t info = { + 1000000, //1Mhz + 32 //32bit counter + }; + return &info; +} + +static void enable_timer0(void) +{ + putreg32(1, S5JS100_TIMER0_BASE + S5JS100_TIMER_UP_DOWN_SEL); // Set Up count + putreg32(0x0, S5JS100_TIMER0_BASE + S5JS100_TIMER_LOAD_VALUE); + putreg32(0x1, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_ENABLE); + putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_SEL); + putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_ENABLE); + putreg32(3, S5JS100_TIMER0_BASE + S5JS100_TIMER_CONTROL); +} + +static void disable_timer0(void) +{ + putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_CONTROL); + putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_UP_DOWN_SEL); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_LOAD_VALUE); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_SEL); + putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_ENABLE); + putreg32(0x0, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_ENABLE); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE); +} + +static void enable_timer1(void) +{ + putreg32(1, S5JS100_TIMER1_BASE + S5JS100_TIMER_UP_DOWN_SEL); // Set Up count + putreg32(0x0, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_VALUE); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_SEL); + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE); + putreg32(3, S5JS100_TIMER1_BASE + S5JS100_TIMER_CONTROL); +} + +static void disable_timer1(void) +{ + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_UP_DOWN_SEL); + putreg32(0xFFFFFFFF, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_VALUE); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_SEL); + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_CONTROL); + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE); +} + +void __us_ticker_irq_handler(void) +{ + us_ticker_disable_interrupt(); + us_ticker_clear_interrupt(); + us_ticker_irq_handler(); +} + +void us_ticker_init(void) +{ + /** + ** We use two timer, timer0 channel to be used timer and timer1 to be used compare timer + **/ + + if (!us_ticker_initialized) { + us_ticker_initialized = 1; + /* Enable timer0 to timer */ + enable_timer0(); + /* Enable timer1 to compare and Disable timer1 interrupt */ + enable_timer1(); + /* Install the interrupt handler(timer0) */ + NVIC_SetVector((IRQn_Type)S5JS100_IRQ_TINT1, (uint32_t)__us_ticker_irq_handler); + NVIC_EnableIRQ((IRQn_Type)S5JS100_IRQ_TINT1); + return; + } + /* Re_init should Disable timer1(compare) interrupt */ + us_ticker_disable_interrupt(); + us_ticker_clear_interrupt(); +} + +uint32_t us_ticker_read() +{ + /* from timer0 read count value */ + if (!us_ticker_initialized) { + us_ticker_init(); + } + volatile uint32_t current_count = getreg32(S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE) / 26; + g_us_last_return = current_count; + return current_count; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) +{ + if (timestamp < 0x70000000 && timestamp != 0) { + uint32_t temp = g_us_last_return; + us_user_intset = timestamp - g_us_last_return; + /* keep to check + if (us_user_intset < 0) { + us_ticker_irq_handler(); + return; + }*/ + us_user_intset = us_user_intset * 26; + uint32_t past_tick = us_ticker_read() - temp; + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_CON_VALUE); + putreg32(us_user_intset - past_tick * 26, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_SEL); + us_ticker_enable_interrupt(); + } else { + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_CON_VALUE); + putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_SEL); + us_ticker_enable_interrupt(); + } +} + +void us_ticker_fire_interrupt(void) +{ + NVIC_SetPendingIRQ((IRQn_Type)S5JS100_IRQ_TINT1); +} + +void us_ticker_disable_interrupt(void) +{ + putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE); +} + +void us_ticker_enable_interrupt(void) +{ + putreg32(1, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE); +} + +void us_ticker_clear_interrupt(void) +{ + putreg32(1, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_CLEAR); + NVIC_ClearPendingIRQ((IRQn_Type)S5JS100_IRQ_TINT1); +} + +void us_ticker_free(void) +{ + us_ticker_initialized = 0; + disable_timer1(); + NVIC_DisableIRQ((IRQn_Type)S5JS100_IRQ_TINT1); + disable_timer0(); +} + +#endif // DEVICE_USTICKER diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.h b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.h new file mode 100644 index 0000000000..b1b1358261 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ +#define S5JS100_TIMER_LOAD_VALUE 0x00 +#define S5JS100_TIMER_CONTROL 0x04 + +#define S5JS100_TIMER_CNT_CON_MASK (1 << 1) +#define S5JS100_TIMER_CNT_CON_SINGLESHOT (0 << 1) +#define S5JS100_TIMER_CNT_CON_RELOAD (1 << 1) + +#define S5JS100_TIMER_CNT_EN_MASK (1 << 0) +#define S5JS100_TIMER_CNT_EN (1 << 0) +#define S5JS100_TIMER_CNT_DIS (0 << 0) + +#define S5JS100_TIMER_LOAD_CON_VALUE 0x08 +#define S5JS100_TIMER_INT_STATUS 0x0C +#define S5JS100_TIMER_INT_CLEAR 0x10 +#define S5JS100_TIMER_INT_ENABLE 0x14 +#define S5JS100_TIMER_UP_DOWN_SEL 0x18 +#define S5JS100_TIMER_INT_SEL 0x1C +#define S5JS100_TIMER_FAKE_READ_DISABLE 0x20 +#define S5JS100_TIMER_DUMP_ENABLE 0x24 +#define S5JS100_TIMER_DUMP_READ 0x28 +#define S5JS100_TIMER_ALL_DUMP_READ 0x2C +#define S5JS100_TIMER_CDC_ENABLE 0x30 +#define S5JS100_TIMER_COUNT_VALUE 0x34 +#define S5JS100_TIMER_DUMP_COUNT_VALUE 0x38 +#define S5JS100_TIMER_ALL_DUMP_COUNT_VALUE 0x3C +#define S5JS100_TIMER_CDC_COUNT_VALUE 0x40 +#define S5JS100_TIMER_PCLK_CTRL 0x44 +#define S5JS100_TIMER_ALL_DUMP_ENABLE 0x800 diff --git a/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/watchdog_api.c b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/watchdog_api.c new file mode 100644 index 0000000000..e977600cc0 --- /dev/null +++ b/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/watchdog_api.c @@ -0,0 +1,307 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include "cmsis_os.h" +#include "cmsis.h" + +#if DEVICE_WATCHDOG +#define WATCHDOG_RESET_ENABLED 1 +#include "watchdog_api.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void s5js100_watchdog_irq_enable(void); +static void s5js100_watchdog_irq_disable(void); +static void s5js100_watchdog_ack_irq(void); +static void s5js100_watchdog_reset_enable(void); +static void s5js100_watchdog_reset_disable(void); +static void s5js100_watchdog_enable(void); +static void s5js100_watchdog_disable(void); +static uint32_t s5js100_watchdog_getclock(void); +static void s5js100_watchdog_handler(void); +static void s5js100_watchdog_set_reload_val(uint32_t time_ms); +static void s5js100_watchdog_set_load_val_diff(uint32_t time_ms); +static uint32_t s5js100_watchdog_get_curr(void); +static void s5js100_watchdog_set_curr(unsigned int curr_val); +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +// REGISTERS +#define rWDOG_CTRL 0x00 +#define bWDOG_CNT_EN (2) +#define bWDOG_PCLK_EN (1) +#define bWDOG_WCLK_EN (0) + +#define rWDOG_LOAD_VAL 0x04 +#define rWDOG_LOAD 0x08 +#define rWDOG_RESET_REQ_EN 0x0C +#define rWDOG_INT_EN 0x10 +#define rWDOG_INT_STAT_RAW 0x14 +#define rWDOG_INT_STAT_MASKED 0x18 +#define rWDOG_INT_CLR 0x1C +#define rWDOG_CNT_UPD_EN 0x20 +#define rWDOG_CNT_VAL 0x24 +#define rWDOG_RESET_REQN_STAT 0x28 +#define rWDOG_LOAD_VAL_DIFF 0x2C +#define rWDOG_BLK_CTRL 0x800 + +#define EXT_SLPCLK 32768 + +/* Hold initially-configured timeout in hal_watchdog_init */ +static uint32_t wdt_timeout_reload_ms = 0; + + +static uint32_t s5js100_watchdog_getclock(void) +{ + /* TODO: get TCLKB from CLK DRIVER */ + return EXT_SLPCLK; +} + +watchdog_status_t hal_watchdog_init(const watchdog_config_t *config) +{ + /* Check validity of arguments */ + if (! config || ! config->timeout_ms) { + return WATCHDOG_STATUS_INVALID_ARGUMENT; + } + + wdt_timeout_reload_ms = config->timeout_ms; + + //clear Watchdog + s5js100_watchdog_disable(); + + // Set WDT interrupt + NVIC_SetVector(S5JS100_IRQ_WDG, (uint32_t) s5js100_watchdog_handler); +#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + SCB_InvalidateICache(); +#endif + NVIC_EnableIRQ(S5JS100_IRQ_WDG); + +#if WATCHDOG_RESET_ENABLED + s5js100_watchdog_reset_enable(); +#endif + s5js100_watchdog_set_reload_val(wdt_timeout_reload_ms); + + s5js100_watchdog_enable(); + + return WATCHDOG_STATUS_OK; +} + +void hal_watchdog_kick(void) +{ + s5js100_watchdog_set_reload_val(wdt_timeout_reload_ms); +} + +watchdog_status_t hal_watchdog_stop(void) +{ +// printf("%s\r\n", __func__); + s5js100_watchdog_disable(); + return WATCHDOG_STATUS_OK; +} + +uint32_t hal_watchdog_get_reload_value(void) +{ + return wdt_timeout_reload_ms; +} + +watchdog_features_t hal_watchdog_get_platform_features(void) +{ + watchdog_features_t wdt_feat; + + /* We can support timeout values between 1 and UINT32_MAX by cascading. */ + wdt_feat.max_timeout = UINT32_MAX; + /* Support re-configuring watchdog timer */ + wdt_feat.update_config = 1; + /* Support stopping watchdog timer */ + wdt_feat.disable_watchdog = 1; + + return wdt_feat; +} + +static void s5js100_watchdog_handler(void) +{ + s5js100_watchdog_ack_irq(); +} + +/**************************************************************************** + * Name: s5js100_watchdog_disable + * + * Description: + * Disable the watchdog timer. The S5J always boots with the watchdog + * timer enabled at timeout of 10 - 20 seconds by the second stage boot + * loader to detect any boot failure. So, the watchdog timer must be + * disabled as part of the start up logic. + * + ****************************************************************************/ +static void s5js100_watchdog_disable(void) +{ + putreg32(0, S5JS100_WDT_BASE + rWDOG_CNT_UPD_EN); + modifyreg32(S5JS100_WDT_BASE + rWDOG_CTRL, (1 << bWDOG_CNT_EN), 0); +} + +/**************************************************************************** + * Name: s5js100_watchdog_enable + * + * Description: + * Enable watchdog operation. + * Should be correctly configured before enabling. + * + ****************************************************************************/ +static void s5js100_watchdog_enable(void) +{ + putreg32(1, S5JS100_WDT_BASE + rWDOG_CNT_UPD_EN); + modifyreg32(S5JS100_WDT_BASE + rWDOG_CTRL, (0x1 << bWDOG_CNT_EN), (0x1 << bWDOG_CNT_EN)); +} + +/**************************************************************************** + * Name: s5js100_watchdog_reset_disable + * + * Description: + * When WD timer expires, it can issue HW reset. + * This function disables reset feature. + * Watchdog will be reloaded with value written in reload register. + * and continue its operation. + * + ****************************************************************************/ +static void s5js100_watchdog_reset_disable(void) +{ + putreg32(0, S5JS100_WDT_BASE + rWDOG_RESET_REQ_EN); +} + +/**************************************************************************** + * Name: s5js100_watchdog_reset_enable + * + * Description: + * When WD timer expires, it can issue HW reset. + * This function enables reset feature. + * + ****************************************************************************/ +static void s5js100_watchdog_reset_enable(void) +{ + putreg32(1, S5JS100_WDT_BASE + rWDOG_RESET_REQ_EN); + putreg32(1 << 1, 0x82020018); + +} + +static void s5js100_watchdog_ack_irq(void) +{ + putreg32(0, S5JS100_WDT_BASE + rWDOG_INT_CLR); +} + +/**************************************************************************** + * Name: s5js100_watchdog_irq_disable + * + * Description: + * When WD timer expires, it can issue interrupt. + * This function disables reset feature. + * + ****************************************************************************/ +static void s5js100_watchdog_irq_disable(void) +{ + putreg32(0, S5JS100_WDT_BASE + rWDOG_INT_EN); +} + +/**************************************************************************** + * Name: s5js100_watchdog_irq_enable + * + * Description: + * When WD timer expires, it can issue interrupt. + * This function enables reset feature. + * + ****************************************************************************/ +static void s5js100_watchdog_irq_enable(void) +{ + putreg32(1, S5JS100_WDT_BASE + rWDOG_INT_EN); +} + +/**************************************************************************** + * Name: s5js100_watchdog_set_reload_val + * + * Description: + * When WD timer expires, if reset is disabled, will be reloaded with value + * defined by this function call. + * + ****************************************************************************/ +static void s5js100_watchdog_set_reload_val(uint32_t time_ms) +{ + uint32_t slp_clk = s5js100_watchdog_getclock(); + uint32_t load_value; + + load_value = (time_ms * slp_clk) / 1000; + putreg32(load_value, S5JS100_WDT_BASE + rWDOG_LOAD_VAL); + putreg32(0x1, S5JS100_WDT_BASE + rWDOG_LOAD); +} + +/**************************************************************************** + * Name: s5js100_watchdog_set_load_val_diff + * + * Description: + * Funtion s5js100_watchdog_set_load_val_diff set LOAD_VAL_DIFF value. + * This value sets the difference between interrupt assertion time and + * the reset request assertion time. The interrupt assertion occurs before + * the reset request as this value. This value should be stable before writing + * 1 to LOAD register. + * + ****************************************************************************/ +static void s5js100_watchdog_set_load_val_diff(uint32_t time_ms) +{ + uint32_t slp_clk = s5js100_watchdog_getclock(); + uint32_t load_diff; + + load_diff = (time_ms * slp_clk) / 1000; + putreg32(load_diff, S5JS100_WDT_BASE + rWDOG_LOAD_VAL_DIFF); +} + +/**************************************************************************** + * Name: s5js100_watchdog_get_curr + * + * Description: + * Function s5js100_watchdog_get_curr returns current WD counter value. + ****************************************************************************/ +static uint32_t s5js100_watchdog_get_curr(void) +{ + uint32_t slp_clk = s5js100_watchdog_getclock(); + uint32_t load_value; + + load_value = getreg32(S5JS100_WDT_BASE + rWDOG_CNT_VAL); + + return ((load_value * 1000) / slp_clk); +} + +/**************************************************************************** + * Name: s5js100_watchdog_set_curr + * + * Description: + * Function s5js100_watchdog_set_curr sets immediately current WD counter value. + * Use this function to set initial WD timer value before running operation. + ****************************************************************************/ +static void s5js100_watchdog_set_curr(unsigned int curr_val) +{ + putreg32(curr_val, S5JS100_WDT_BASE + rWDOG_LOAD_VAL); + putreg32(0x1, S5JS100_WDT_BASE + rWDOG_LOAD); +} + +#endif diff --git a/targets/TARGET_Samsung/security_subsystem/api/trng_api.c b/targets/TARGET_Samsung/security_subsystem/api/trng_api.c new file mode 100644 index 0000000000..994949d9de --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/api/trng_api.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "hal/trng_api.h" +#include "sss_driver_rng.h" + +void trng_init(trng_t *obj) +{ + (void)obj; +} + +void trng_free(trng_t *obj) +{ + (void)obj; +} + +int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length) +{ + (void)obj; + + stOCTET_STRING stRANDOM; + unsigned int ret = 0; + + stRANDOM.pu08Data = (u08 *)output; + ret = sss_generate_rawrandom(&stRANDOM, length); + + *output_length = (size_t)stRANDOM.u32DataByteLen; + + if (ret) { + printf("Fail to get RNG value from SSS(0x%08x)\r\n", ret); + } + + return ret; +} diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.c b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.c new file mode 100644 index 0000000000..a1cfcbe613 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.c @@ -0,0 +1,163 @@ +/**************************************************************************/ +/* Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. */ +/* */ +/* -INSTRUCTIONS- */ +/* THIS SOFTWARE IS A CONFIDENTIAL STUFFS AND PROPRIETARY OF SAMSUNG ELEC */ +/* TRONICS CO.,LTD. SO YOU SHALL NOT DISCLOSE THIS SOFTWARE OTHER COMPANY */ +/* OR PERSONS WITHOUT PERMISSION OF SAMSUNG AND SHALL USE THIS SOFTWARE */ +/* ONLY IN ACCORDANCE WITH THE LICENSE AGREEMENT OF SAMSUNG. */ +/* SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY */ +/* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED */ +/* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */ +/* PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE LIABLE FOR ANY */ +/* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR */ +/* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ +/**************************************************************************/ + +/*************** Include Files ********************************************/ +/* Driver Common */ +#include "sss_common.h" +#include "sss_driver_util.h" +#include "sss_map.h" +#include "sss_driver_error.h" +#include "mb_cmd_system.h" + +/* Driver Algorithm */ +#include "mb_cmd_hash.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ +const unsigned char pu08hash_wlen[8] = { 0, 5, 7, 8, 12, 16, 0, 0 }; + +/*************** Functions ***********************************************/ + + +/*! @fn mb_hash_init(unsigned int object_id, unsigned int msg_byte_len) + * @ingroup SECURITY_SSS_MAILBOX + * @brief mailbox api for hash to init. hash setting + * @version v0.50 : 2016.8.13 Init. release version + * @param[in] object_id : algorithm selection + * @param[in] msg_byte_len : length of message with byte unit + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int mb_hash_init( + const stOCTET_STRING *pstMessage, + unsigned int object_id) +{ + + unsigned int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + + //! step 1-1 : set data field + SSS_DATA_FIELD_SET(0U, pstMessage->u32DataByteLen); + + //! step 1-2 : set control field + SSS_SET_MB_OID(object_id); + + //! step 2 : run mb_cmd + ret = sss_mb_command(FUNC_HASH_INIT); + + return ret; +} + + + +/*! @fn mb_hash_update(unsigned int block_byte_len, unsigned char * msg_block) + * @ingroup SECURITY_SSS_MAILBOX + * @brief mailbox api for hash to update partial block of message + * @version v0.50 : 2016.8.13 Init. release version + * @param[in] block_byte_len: length of partial block message. It differ from hash algorithm spec. + * @param[in] msg_block : partial message block with block_byte_len + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int mb_hash_update( + stOCTET_STRING *pstMessage, + unsigned int block_byte_len) +{ + int ret = SSSR_SUCCESS; + + //! step 1 : digest + while (pstMessage->u32DataByteLen > MAX_MB_HASH_BLOCK_BLEN) { + + //! - check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + + //! Set data field : message + ret = _sss_OS_to_MB(pstMessage, (unsigned int *)(SSS_DATA_FIELD_BASE), MAX_MB_HASH_BLOCK_BLEN); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! Run mb_cmd + ret = sss_mb_command(FUNC_HASH_UPDATE); + + pstMessage->pu08Data += MAX_MB_HASH_BLOCK_BLEN; + pstMessage->u32DataByteLen -= MAX_MB_HASH_BLOCK_BLEN; + + } + + return ret; +} + + + +/*! + * @ingroup SECURITY_SSS_MAILBOX + * @brief mailbox api for hash to update partial block of message + * @version v0.50 : 2016.8.13 Init. release version + * @param[out] hash : hash output + * @param[in] block_byte_len: length of last block message. + * @param[in] msg_block : last message block with block_byte_len + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int mb_hash_final( + stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest) +{ + unsigned int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + + //! set data field + // Check boudary of msg_block + if (pstMessage->u32DataByteLen > MAX_MB_HASH_BLOCK_BLEN) { + return ERROR_HASH_INVALID_LEN_BLOCK; + } + + ret = _sss_OS_to_MB(pstMessage, (unsigned int *)(SSS_DATA_FIELD_BASE), pstMessage->u32DataByteLen); + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 2 : run mb_cmd + ret = sss_mb_command(FUNC_HASH_FINAL); + if (ret == SSSR_SUCCESS) { + ret = sss_mb_get_response(pstDigest); + } + + return ret; +} + + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.h b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.h new file mode 100644 index 0000000000..6248548f59 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_hash.h @@ -0,0 +1,76 @@ +/**************************************************************************/ +/* Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. */ +/* */ +/* -INSTRUCTIONS- */ +/* THIS SOFTWARE IS A CONFIDENTIAL STUFFS AND PROPRIETARY OF SAMSUNG ELEC */ +/* TRONICS CO.,LTD. SO YOU SHALL NOT DISCLOSE THIS SOFTWARE OTHER COMPANY */ +/* OR PERSONS WITHOUT PERMISSION OF SAMSUNG AND SHALL USE THIS SOFTWARE */ +/* ONLY IN ACCORDANCE WITH THE LICENSE AGREEMENT OF SAMSUNG. */ +/* SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY */ +/* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED */ +/* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */ +/* PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE LIABLE FOR ANY */ +/* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR */ +/* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ +/**************************************************************************/ + +#ifndef SSS_MB_CMD_HASH_H +#define SSS_MB_CMD_HASH_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +#define MAX_HASH_BLOCK_BLEN (128) //when sha2 + +//!mailbox command + +#define FUNC_HASH_INIT (0x00013101) +#define FUNC_HASH_UPDATE (0x00023101) +#define FUNC_HASH_FINAL (0x00033101) + + +/*************** New Data Types (Basic Data Types) ***********************/ + +//! @struct sHASH_MSG +//! @brief struct of message for Hash +struct sHASH_MSG { + + unsigned int addr_low; + + unsigned int addr_high; + + unsigned int descriptor_byte_len; + + unsigned int msg_byte_len; + + unsigned int msg_type; +}; + +#define MAX_MB_HASH_BLOCK_BLEN (256) + + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +unsigned int mb_hash_init( + const stOCTET_STRING *pstMessage, + unsigned int object_id); + +unsigned int mb_hash_update( + stOCTET_STRING *pstMessage, + unsigned int block_byte_len); + +unsigned int mb_hash_final( + stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest); + +#endif /* SSS_MB_CMD_HASH_H */ + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.c b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.c new file mode 100644 index 0000000000..5719cf4057 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 Files ********************************************/ +/* Driver Common */ +#include "sss_common.h" +#include "sss_driver_util.h" +#include "sss_map.h" +#include "sss_driver_error.h" +#include "mb_cmd_system.h" + +/* Driver Algorithm */ +#include "mb_cmd_rng.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +/*! @fn mb_generate_random_number(unsigned int *random_number, unsigned int random_wlen) + * @ingroup SECURITY_SSS_MAILBOX + * @brief mailbox api for random number generation + * @version v0.50 : 2016.8.13 Init. release version + * @version v0.51 : 2018.01.13 Modifyh for S111 SRAM code + * @param[out] random_number : array of random number + * @param[in] random_wlen : word length of random number + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int mb_generate_random_number(stOCTET_STRING *pstRandom, unsigned int request_byte_len) +{ + unsigned int ret; + unsigned int rsp_byte_len; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + + //! set data field + // Check boudary of msg_block + if (request_byte_len > 256) { + return ERROR_RNG_INVALID_LEN_REQUEST; + } + + //! step 1-2 : set control field + SSS_CTRL_FIELD_SET(1U, request_byte_len); + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(FUNC_RNG); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x01); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + if (ret == RSP_SUCCESS) { + SSS_CTRL_FIELD_GET(1U, rsp_byte_len); + ret = _sss_MB_to_OS(pstRandom, (unsigned int *)(SSS_DATA_FIELD_BASE), rsp_byte_len); + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} + + +/*! @fn mb_generate_random_number(unsigned int *random_number, unsigned int random_wlen) + * @ingroup SECURITY_SSS_MAILBOX + * @brief mailbox api for random number generation + * @version v0.50 : 2016.8.13 Init. release version + * @version v0.51 : 2018.01.13 Modifyh for S111 SRAM code + * @param[out] random_number : array of random number + * @param[in] random_wlen : word length of random number + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int mb_generate_raw_random(stOCTET_STRING *pstRandom, unsigned int request_byte_len) +{ + unsigned int ret; + unsigned int rsp_byte_len; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + + + //! set data field + // Check boudary of msg_block + if (request_byte_len > 256U) { + return ERROR_RNG_INVALID_LEN_REQUEST; + } + + //! step 1-2 : set control field + SSS_CTRL_FIELD_SET(1U, request_byte_len); + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(FUNC_TRNG); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x01); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + if (ret == RSP_SUCCESS) { + SSS_CTRL_FIELD_GET(1U, rsp_byte_len); + ret = _sss_MB_to_OS(pstRandom, (unsigned int *)(SSS_DATA_FIELD_BASE), rsp_byte_len); + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} + + + +unsigned int mb_KAT_RNG(void) +{ + unsigned int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(FUNC_RNG_KAT); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x01); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + if (ret == RSP_SUCCESS) { + ret = SSSR_SUCCESS; + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.h b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.h new file mode 100644 index 0000000000..c96c2ee020 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_rng.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MB_CMD_RNG_H +#define MB_CMD_RNG_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +// ====================================== +// Mailbox Command +// ====================================== +#define FUNC_RNG (0x00016101) +#define FUNC_TRNG (0x00026101) +#define FUNC_RNG_KAT (0x00A06101) + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +unsigned int mb_generate_random_number(stOCTET_STRING *pstRandom, unsigned int request_byte_len); +unsigned int mb_generate_raw_random(stOCTET_STRING *pstRandom, unsigned int request_byte_len); +unsigned int mb_KAT_RNG(void); + + +#endif /* MB_CMD_RNG_H */ + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.c b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.c new file mode 100644 index 0000000000..f12e4965b6 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.c @@ -0,0 +1,264 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 Files ********************************************/ +#include "sss_map.h" +#include "sss_driver_error.h" +#include "sss_driver_util.h" +#include "mb_cmd_system.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +unsigned int mb_system_clear(unsigned int type) +{ + int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + //! set data field + + //! step 1-2 : set control field + SSS_CTRL_FIELD_SET(1U, type); + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(FUNC_SYSTEM_CLEAR); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x01); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + + if (ret == RSP_SUCCESS) { + ret = SUCCESS; + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} + + +unsigned int mb_system_get_info(unsigned int *version) +{ + + int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + //! set data field + + //! step 1-2 : set control field + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(FUNC_SYSTEM_GET_INFO); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x03); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + + if (ret == RSP_SUCCESS) { + //_isp_memcpy_mailbox((unsigned int *)version , (unsigned int *)(DATA_FIELD_BASE), 8); + *version++ = SSS_DATA_FIELD(0); + *version++ = SSS_DATA_FIELD(1); + ret = SUCCESS; + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} + + +unsigned int mb_system_get_info_sram(unsigned int *version) +{ + + int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + //! set data field + + //! step 1-2 : set control field + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(0x00000102); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x03); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + + if (ret == RSP_SUCCESS) { + //_isp_memcpy_mailbox((unsigned int *)version , (unsigned int *)(DATA_FIELD_BASE), 8); + *version++ = SSS_DATA_FIELD(0); + *version++ = SSS_DATA_FIELD(1); + ret = SUCCESS; + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} + + +unsigned int mb_system_fw_loading(unsigned int u32REMAP_ADDR, unsigned int u32SFR_REMAP_ADDR) +{ + + int ret; + + //! step 0 : check the status of mailbox + if (SSS_MB_STATUS) { + return ERROR_SYSTEM_MAILBOX_BUSY; + } + //! set data field + SSS_DATA_FIELD_SET(0, u32REMAP_ADDR); + + SSS_DATA_FIELD_SET(1, u32SFR_REMAP_ADDR); + + //! step 1-2 : set control field + + //! step 2 : run mb_cmd + SSS_SET_MB_COMMAND(FUNC_SYSTEM_SELF_LOAD); + + //! step 3 : wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x01); + + //! step 4 : get return value// get return value + SSS_GET_MB_RESULT(ret); + + if (ret == RSP_SUCCESS) { + ret = SSSR_SUCCESS; + } else { + SSS_GET_ERROR_CODE(ret); + } + + return ret; +} + + +unsigned int sss_mb_command(unsigned int u32Command) +{ + unsigned int ret; + + //! - Run mb_cmd + SSS_SET_MB_COMMAND(u32Command); + + //! - Wait for response + WAIT_SFR_BIT_CLR(SSS_MB_STATUS, 0x01); + + //! - Check result + ret = sss_mb_check_error(); + return ret; +} + + +unsigned int sss_mb_check_n_get_response(stOCTET_STRING *pstOutput, unsigned int u32ExpecedLen) +{ + unsigned int ret; + unsigned int rsp_block_byte_len; + + SSS_GET_RSP_LEN(rsp_block_byte_len); + + if (rsp_block_byte_len == u32ExpecedLen) { + + ret = _sss_MB_to_OS(pstOutput, (unsigned int *)(SSS_DATA_FIELD_BASE), rsp_block_byte_len); + } else { + return ERROR_INVALID_LEN_RSP_BLOCK; + } + + return ret; +} + + +unsigned int sss_mb_get_response(stOCTET_STRING *pstOutput) +{ + unsigned int ret; + unsigned int rsp_block_byte_len; + + SSS_GET_RSP_LEN(rsp_block_byte_len); + ret = _sss_MB_to_OS(pstOutput, (unsigned int *)(SSS_DATA_FIELD_BASE), rsp_block_byte_len); + + return ret; +} + + +unsigned int sss_mb_check_n_get_response_BN(stBIG_NUM *pstOutput, unsigned int u32ExpecedLen) +{ + unsigned int ret; + unsigned int rsp_block_byte_len; + + SSS_GET_RSP_LEN(rsp_block_byte_len); + + if (rsp_block_byte_len == u32ExpecedLen) { + ret = _sss_MB_to_BN(pstOutput, (unsigned int *)(SSS_DATA_FIELD_BASE), rsp_block_byte_len); + } else { + return ERROR_INVALID_LEN_RSP_BLOCK; + } + + return ret; +} + + +unsigned int sss_mb_get_response_BN(stBIG_NUM *pstOutput) +{ + unsigned int ret; + unsigned int rsp_block_byte_len; + + SSS_GET_RSP_LEN(rsp_block_byte_len); + ret = _sss_MB_to_BN(pstOutput, (unsigned int *)(SSS_DATA_FIELD_BASE), rsp_block_byte_len); + + return ret; +} + + +unsigned int sss_mb_check_error(void) +{ + unsigned int ret; + + SSS_GET_MB_RESULT(ret); + + if (ret == RSP_SUCCESS) { + ret = SSSR_SUCCESS; + } else { + SSS_GET_ERROR_CODE(ret); + } + return ret; +} + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.h b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.h new file mode 100644 index 0000000000..04f7cab182 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/mb_cmd_system.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 MB_CMD_SYSTEM_H +#define MB_CMD_SYSTEM_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +#define CLEAR_TYPE_MAILBOX (0x00) +#define CLEAR_TYPE_ALL (0xff) + +#define ERROR_INVALID_LEN_RSP_BLOCK (FROM_DRV | (INVALID_LEN | ERR_OUTPUT)) + +//! Mailbox Command +#define FUNC_SYSTEM_GET_INFO (0x00000101) +#define FUNC_SYSTEM_CLEAR (0x00000201) +#define FUNC_SYSTEM_SELF_LOAD (0x00000501) + + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +/*! + * @brief mailbox command for clear function + * @param[in] type definition of clear level {} + + * @return + + Error Code Description + SSSR_SUCCESS Function operates normally + Others(!=0) fail - error from sub-function + + * @author Jinsu Hyun + * @version V0.5 + + Version Date Person Description + V0.50 2016.08.13 jinsu Initial Version + V0.51 2018.01.04 kitak Modify for S111 SRAM code + + */ +unsigned int mb_system_clear(unsigned int type); + +/*! + * @brief mailbox command for get info function + * @param[in] version ??? ??? + + * @return + + Error Code Description + SSSR_SUCCESS Function operates normally + Others(!=0) fail - error from sub-function + + * @author Jinsu Hyun + * @version V0.5 + + Version Date Person Description + V0.50 2016.08.13 jinsu Initial Version + V0.51 2018.01.04 kitak Modify for S111 SRAM code + + */ +unsigned int mb_system_get_info(unsigned int *version); + +unsigned int mb_system_get_info_sram(unsigned int *version); + + +/** + * @brief mailbox command for self-loading + * @param[in] u32SrcAddr Address of FW to be loaded + * @return + + Error Code Description + SSSR_SUCCESS Function operates normally + ERROR_IP_BUSY + ERROR_INVALID_OID_SIZE + + * @author kiseok.bae (kiseok.bae@samsung.com) + * @version V0.00 + + Version Date Person Description + V0.00 2017.07.15 kiseok Initial Version + V0.51 2018.01.04 kitak Modify for S111 SRAM code + */ +unsigned int mb_system_fw_loading(unsigned int u32REMAP_ADDR, unsigned int u32SFR_REMAP_ADDR); + + +unsigned int sss_mb_command(unsigned int u32Command); +unsigned int sss_mb_check_error(void); +unsigned int sss_mb_check_n_get_response(stOCTET_STRING *pstOutput, unsigned int u32ExpecedLen); +unsigned int sss_mb_get_response(stOCTET_STRING *pstOutput); +unsigned int sss_mb_get_response_BN(stBIG_NUM *pstOutput); +unsigned int sss_mb_check_n_get_response_BN(stOCTET_STRING *pstOutput, unsigned int u32ExpecedLen); + +#endif /* MB_CMD_SYSTEM_H */ + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_common.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_common.h new file mode 100644 index 0000000000..b939a46af9 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_common.h @@ -0,0 +1,159 @@ +/**************************************************************************/ +/* Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. */ +/* */ +/* -INSTRUCTIONS- */ +/* THIS SOFTWARE IS A CONFIDENTIAL STUFFS AND PROPRIETARY OF SAMSUNG ELEC */ +/* TRONICS CO.,LTD. SO YOU SHALL NOT DISCLOSE THIS SOFTWARE OTHER COMPANY */ +/* OR PERSONS WITHOUT PERMISSION OF SAMSUNG AND SHALL USE THIS SOFTWARE */ +/* ONLY IN ACCORDANCE WITH THE LICENSE AGREEMENT OF SAMSUNG. */ +/* SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY */ +/* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED */ +/* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */ +/* PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE LIABLE FOR ANY */ +/* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR */ +/* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ +/**************************************************************************/ + +#ifndef SSS_COMMON_H +#define SSS_COMMON_H + +/*************** Include Files ********************************************/ +#include "sss_oid.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +#define SUCCESS (0x00) +#define FAIL (0x01) + +#define SSSR_SUCCESS (0x00) +#define SSSR_FAIL (0x01) + +#define RSP_FAIL (0xF1) +#define RSP_SUCCESS (0xA1) + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define NULLPTR (void *)0 + + +///////////////////////////////////////////////////////// +// MACRO //////////////////////////////////////////////// +///////////////////////////////////////////////////////// +#define BIT(nbit) (0x1u << (nbit)) +#define SFR_BIT_SET(val, bit) ((val) |= (bit)) ///> 0)); \ + ((u08 *)(buf))[2] = ((u08)((dword) >> 8)); \ + ((u08 *)(buf))[1] = ((u08)((dword) >> 16)); \ + ((u08 *)(buf))[0] = ((u08)((dword) >> 24)); + +#define GET_DWORD_FROM_BBUF(buf) \ + (u32)( \ + ((((u08 *)(buf))[3]) << 0) | \ + ((((u08 *)(buf))[2]) << 8) | \ + ((((u08 *)(buf))[1]) << 16) | \ + ((((u08 *)(buf))[0]) << 24)) + +#define SWAP32(val) \ + (u32)( \ + (((val) & 0xff) << 24) | \ + (((val) & 0xff00) << 8) | \ + (((val) & 0xff0000) >> 8) | \ + (((val) & 0xff000000) >> 24) \ + ) + + +#define CEIL_16BYTE(val) (val&0xF) ? ((val&0xFFFFFFF0)+0x10) : (val) +#define CEIL_BY_WORD(val) (((val)+3)>>2) +#define CEIL_BY_16BYTE(val) (((val)+15)>>4) +//#define CEIL_BY_BYTE(bitval) (((bitval)+7)>>3) + + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ +//! 8bits unsigned data type +typedef unsigned char u08; +//! 16bits unsigned data type +typedef unsigned short u16; +//! 32bits unsigned data type +typedef unsigned int u32; +//! 64bits unsigned data type +typedef unsigned long long u64; +//! CPU size bits unsigned data type +typedef unsigned int uwd; +//! 8bits signed data type +typedef char s08; +//! 16bits signed data type +typedef short s16; +//! 32bits signed data type +typedef int s32; +//! 64bits signed data type +typedef long long s64; +//! CPU size bits signed data type +typedef int swd; + +//! return error code +typedef u32 SSS_RV; + +/** + * @brief struct of OCTET String / length & data + */ +typedef struct _OS_st { + //! byte length of Data + u32 u32DataByteLen; + //! byte array of Data + u08 *pu08Data; +} stOCTET_STRING; + +/** + * @brief struct of BIGNUM String / length & data + */ +typedef stOCTET_STRING stBIG_NUM; + + + + + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + + +#endif /* SSS_COMMON_H */ + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_error.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_error.h new file mode 100644 index 0000000000..3442703ecd --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_error.h @@ -0,0 +1,368 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SSS_DRIVER_ERROR_H +#define SSS_DRIVER_ERROR_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +#define FROM_FW (0x0F) +#define FROM_DRV (0x0D) + +//! Common Error Code +#define ERROR_AES (0x00001000) +#define ERROR_DH (0x00009000) +#define ERROR_ECC (0x00006000) +#define ERROR_ECDSA (0x00007000) +#define ERROR_ECDH (0x00008000) +#define ERROR_PKA (0x0000E000) +#define ERROR_RSA (0x00005000) +#define ERROR_RNG (0x00004000) +#define ERROR_RNG_TRNG (0x00004100) +#define ERROR_SHA (0x00002000) +#define ERROR_HMAC (0x00003000) +#define ERROR_SM3 (0x0000C200) +#define ERROR_SM3_HMAC (0x0000C300) +#define ERROR_SM4 (0x0000C100) +#define ERROR_KM (0x0000A000) +#define ERROR_SWDT1 (0x0000D100) +#define ERROR_SWDT2 (0x0000D200) +#define ERROR_FEEDER (0x0000F000) +#define INVALID_LEN (0x00010000) +#define INVALID_SEL (0x00FE0000) +#define INVALID_VAL (0x00FF0000) +#define INVALID_STS (0x00FD0000) +#define INVALID_SZ (0x00FC0000) +#define INVALID_FORM (0x00FB0000) +#define INVALID_FUNCID00 (0x00F00000) +#define INVALID_FUNCID01 (0x00F10000) +#define INVALID_FUNCID02 (0x00F20000) +#define INVALID_FUNCID03 (0x00F30000) +#define INVALID_ORDER (0x00FA0000) +#define INVALID_STATUS (0x00190000) +#define ERR_CNT (0x01000000) +#define ERR_IV (0x02000000) +#define ERR_TAG (0x03000000) +#define ERR_KEY (0x04000000) +#define ERR_BLOCK (0x05000000) +#define ERR_MSG (0x06000000) +#define ERR_MODE (0x07000000) +#define ERR_OID_ALG (0x08000000) +#define ERR_OID_SIZE (0x09000000) +#define ERR_SIGNATURE (0x0A000000) +#define ERR_PUBLICKEY (0x0B000000) +#define ERR_PRIVKEY (0x1B000000) +#define ERR_ROLLBACK_CNT (0x0C000000) +#define ERR_SIGNER_VER (0x0D000000) +#define ERR_FW (0x0E000000) +#define ERR_OUTPUT (0x0F000000) +#define ERR_BUSY (0x10000000) +#define ERR_CRNGT (0x11000000) +#define ERR_SLOT (0x12000000) +#define ERR_KEYMODE (0x13000000) +#define ERR_KAT (0x14000000) +#define ERR_HT (0x15000000) +#define ERR_RANDOM (0x16000000) +#define ERR_SALT (0x17000000) +#define ERR_PUF (0x18000000) +#define ERR_ERR_RATE (0x19000000) +#define ERR_MB_CMD (0x20000000) +#define ERR_AAD (0x21000000) +#define ERR_LABEL (0x30000000) +#define ERR_HW (0xFF000000) +#define ERR_DECRYPTION (0xDD000000) + +//! Error From DRV +// System +#define ERROR_SYSTEM_MAILBOX_BUSY (FROM_DRV | (ERR_MB_CMD | INVALID_STATUS | ERR_BUSY)) +#define ERROR_INVALID_VAL_OID (FROM_DRV | (INVALID_VAL | ERR_OID_ALG)) +// AES +#define ERROR_AES_INVALID_LEN_BLOCK (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_BLOCK)) +#define ERROR_AES_INVALID_LEN_RSP_BLOCK (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_OUTPUT)) +#define ERROR_AES_INVALID_LEN_MSG (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_MSG)) +#define ERROR_AES_INVALID_VAL_MODE (FROM_DRV | (ERROR_AES | INVALID_VAL | ERR_MSG)) +#define ERROR_AES_INVALID_LEN_KEY (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_KEY)) +#define ERROR_AES_INVALID_LEN_AAD (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_AAD)) +#define ERROR_AES_INVALID_LEN_IV (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_IV)) +#define ERROR_AES_INVALID_LEN_CNT (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_CNT)) +#define ERROR_AES_INVALID_LEN_TAG (FROM_DRV | (ERROR_AES | INVALID_LEN | ERR_TAG)) +#define ERROR_AES_INVALID_VAL_TAG (FROM_DRV | (ERROR_AES | INVALID_VAL | ERR_TAG)) +// SM4 +#define ERROR_SM4_INVALID_LEN_BLOCK (FROM_DRV | (ERROR_SM4 | INVALID_LEN | ERR_BLOCK)) +#define ERROR_SM4_INVALID_LEN_RSP_BLOCK (FROM_DRV | (ERROR_SM4 | INVALID_LEN | ERR_OUTPUT)) +#define ERROR_SM4_INVALID_LEN_MSG (FROM_DRV | (ERROR_SM4 | INVALID_LEN | ERR_MSG)) +#define ERROR_SM4_INVALID_VAL_MODE (FROM_DRV | (ERROR_SM4 | INVALID_VAL | ERR_MODE)) +#define ERROR_SM4_INVALID_LEN_KEY (FROM_DRV | (ERROR_SM4 | INVALID_LEN | ERR_KEY)) +// Hash +#define ERROR_HASH_INVALID_LEN_BLOCK (FROM_DRV | (ERROR_SHA | INVALID_LEN | ERR_BLOCK)) +#define ERROR_HASH_INVALID_LEN_MSG (FROM_DRV | (ERROR_SHA | INVALID_LEN | ERR_MSG)) +#define ERROR_HASH_INVALID_VAL_MODE (FROM_DRV | (ERROR_SHA | INVALID_LEN | ERR_MODE)) +// HMAC +#define ERROR_HMAC_INVALID_LEN_BLOCK (FROM_DRV | (ERROR_HMAC | INVALID_LEN | ERR_BLOCK)) +#define ERROR_HMAC_INVALID_LEN_MSG (FROM_DRV | (ERROR_HMAC | INVALID_LEN | ERR_MSG)) +#define ERROR_HMAC_INVALID_VAL_MODE (FROM_DRV | (ERROR_HMAC | INVALID_LEN | ERR_MODE)) +#define ERROR_HMAC_INVALID_LEN_KEY (FROM_DRV | (ERROR_HMAC | INVALID_LEN | ERR_KEY)) +// SM3 +#define ERROR_SM3_INVALID_LEN_BLOCK (FROM_DRV | (ERROR_SM3 | INVALID_LEN | ERR_BLOCK)) +#define ERROR_SM3_INVALID_LEN_MSG (FROM_DRV | (ERROR_SM3 | INVALID_LEN | ERR_MSG)) +#define ERROR_SM3_INVALID_VAL_MODE (FROM_DRV | (ERROR_SM3 | INVALID_LEN | ERR_MODE)) +// DH +#define ERROR_DH_INVALID_LEN_PUBKEY (FROM_DRV | (ERROR_DH | INVALID_LEN | ERR_PUBLICKEY)) +#define ERROR_DH_INVALID_LEN_PRIVKEY (FROM_DRV | (ERROR_DH | INVALID_LEN | ERR_PRIVKEY)) +#define ERROR_DH_INVALID_LEN_KEY (FROM_DRV | (ERROR_DH | INVALID_LEN | ERR_OUTPUT)) +// ECDSA +#define ERROR_ECDSA_INVALID_LEN_MSG (FROM_DRV | (ERROR_ECDSA | INVALID_LEN | ERR_MSG)) +#define ERROR_ECDSA_INVALID_LEN_SIGNATURE (FROM_DRV | (ERROR_ECDSA | INVALID_LEN | ERR_SIGNATURE)) +#define ERROR_ECDSA_INVALID_LEN_PUBKEY (FROM_DRV | (ERROR_ECDSA | INVALID_LEN | ERR_PUBLICKEY)) +#define ERROR_ECDSA_INVALID_LEN_PRIVKEY (FROM_DRV | (ERROR_ECDSA | INVALID_LEN | ERR_PRIVKEY)) +//ECDH +#define ERROR_ECDH_INVALID_LEN_PUBKEY (FROM_DRV | (ERROR_ECDH | INVALID_LEN | ERR_PUBLICKEY)) +#define ERROR_ECDH_INVALID_LEN_PRIVKEY (FROM_DRV | (ERROR_ECDH | INVALID_LEN | ERR_PRIVKEY)) +#define ERROR_ECDH_INVALID_LEN_KEY (FROM_DRV | (ERROR_ECDH | INVALID_LEN | ERR_OUTPUT)) +// RSASSA, RSAES +#define ERROR_RSA_INVALID_LEN_MSG (FROM_DRV | (ERROR_RSA | INVALID_LEN | ERR_MSG)) +#define ERROR_RSA_INVALID_LEN_SIGNATURE (FROM_DRV | (ERROR_RSA | INVALID_LEN | ERR_SIGNATURE)) +#define ERROR_RSA_INVALID_LEN_PUBKEY (FROM_DRV | (ERROR_RSA | INVALID_LEN | ERR_PUBLICKEY)) +#define ERROR_RSA_INVALID_LEN_PRIVKEY (FROM_DRV | (ERROR_RSA | INVALID_LEN | ERR_PRIVKEY)) +#define ERROR_RSA_INVALID_LEN_CIPHER (FROM_DRV | (ERROR_RSA | INVALID_LEN | ERR_OUTPUT)) +#define ERROR_RSA_INVALID_LEN_LABEL (FROM_DRV | (ERROR_RSA | INVALID_LEN | ERR_LABEL)) +// RNG +#define ERROR_RNG_INVALID_LEN_REQUEST (FROM_DRV | (ERROR_RNG | INVALID_LEN | ERR_OUTPUT)) + +//! Error From FW +#define FW_ERROR_AES_INVALID_VAL_OID (FROM_FW | (ERROR_AES | INVALID_VAL | ERR_OID_ALG)) +#define FW_ERROR_AES_INVALID_LEN_MSG (FROM_FW | (ERROR_AES | INVALID_LEN | ERR_MSG)) +#define FW_ERROR_AES_INVALID_STS_KEYMODE (FROM_FW | (ERROR_AES | INVALID_STS | ERR_KEYMODE)) +#define FW_ERROR_AES_INVALID_LEN_KEY (FROM_FW | (ERROR_AES | INVALID_LEN | ERR_KEY)) +#define FW_ERROR_AES_INVALID_VAL_TAG (FROM_FW | (ERROR_AES | INVALID_VAL | ERR_TAG)) +#define FW_ERROR_AES_INVALID_LEN_TAG (FROM_FW | (ERROR_AES | INVALID_LEN | ERR_TAG)) +#define FW_ERROR_AES_INVALID_LEN_IV (FROM_FW | (ERROR_AES | INVALID_LEN | ERR_IV)) +#define FW_ERROR_AES_INVALID_LEN_AAD (FROM_FW | (ERROR_AES | INVALID_LEN | ERR_AAD)) +#define FW_ERROR_AES_INVALID_LEN_CNT (FROM_FW | (ERROR_AES | INVALID_LEN | ERR_CNT)) +#define FW_ERROR_DH_INVALID_VAL_OID (FROM_FW | (ERROR_DH | INVALID_VAL | ERR_OID_ALG)) +#define FW_ERROR_DH_INVALID_VAL_KEY (FROM_FW | (ERROR_DH | INVALID_VAL | ERR_KEY)) +#define FW_ERROR_DH_RNG_ERROR (FROM_FW | (ERROR_DH | INVALID_VAL | ERR_RANDOM)) +#define FW_ERROR_ECC_INVALID_VAL_OID (FROM_FW | (ERROR_ECC | INVALID_VAL | ERR_OID_ALG)) +#define FW_ERROR_ECDSA_INVALID_VAL_KEY (FROM_FW | (ERROR_ECDSA | INVALID_VAL | ERR_KEY)) +#define FW_ERROR_ECDH_INVALID_VAL_KEY (FROM_FW | (ERROR_ECDH | INVALID_VAL | ERR_KEY)) +#define FW_ERROR_ECDSA_INVALID_VAL_SIGN (FROM_FW | (ERROR_ECDSA | INVALID_VAL | ERR_SIGNATURE)) +#define FW_ERROR_ECDSA_RNG_ERROR (FROM_FW | (ERROR_ECDSA | INVALID_VAL | ERR_RANDOM)) +#define FW_ERROR_ECDH_RNG_ERROR (FROM_FW | (ERROR_ECDH | INVALID_VAL | ERR_RANDOM)) +#define FW_ERROR_PKA_SFR_SET (FROM_FW | (ERROR_PKA|INVALID_VAL|ERR_HW)) +#define FW_ERROR_RNG_TRNG_INVALID_CLKDIV (FROM_FW | (ERROR_RNG_TRNG | INVALID_VAL | ERR_HT)) +#define FW_ERROR_RNG_TRNG_KAT_ERROR (FROM_FW | (ERROR_RNG_TRNG | INVALID_STS | ERR_KAT)) +#define FW_ERROR_RNG_TRNG_HT_ERROR (FROM_FW | (ERROR_RNG_TRNG | INVALID_STS | ERR_HT)) +#define FW_ERROR_RSA_INVALID_VAL_OID (FROM_FW | (ERROR_RSA | INVALID_VAL | ERR_OID_ALG)) +#define FW_ERROR_RSA_INVALID_LEN_MESSAGE (FROM_FW | (ERROR_RSA | INVALID_LEN | ERR_MSG)) +#define FW_ERROR_RSA_FAIL_DECRYPTION (FROM_FW | (ERROR_RSA | INVALID_STS | ERR_DECRYPTION)) +#define FW_ERROR_RSA_INVALID_LEN_SALT (FROM_FW | (ERROR_RSA | INVALID_LEN | ERR_SALT)) +#define FW_ERROR_RSA_INVALID_VAL_SIGNATURE (FROM_FW | (ERROR_RSA | INVALID_VAL | ERR_SIGNATURE)) +#define FW_ERROR_RSA_INVALID_LEN_SIGNATURE (FROM_FW | (ERROR_RSA | INVALID_LEN | ERR_SIGNATURE)) +#define FW_ERROR_SHA_INVALID_VAL_OID (FROM_FW | (ERROR_SHA | INVALID_VAL | ERR_OID_ALG)) +#define FW_ERROR_HASH_INVALID_LEN_MSG (FROM_FW | (ERROR_SHA | INVALID_LEN | ERR_MSG)) +#define FW_ERROR_HMAC_INVALID_LEN_KEY (FROM_FW | (ERROR_HMAC | INVALID_LEN | ERR_KEY)) +#define FW_ERROR_SM3_INVALID_VAL_OID (FROM_FW | (ERROR_SM3 | INVALID_VAL | ERR_OID_ALG)) +#define FW_ERROR_SM3_INVALID_LEN_MSG (FROM_FW | (ERROR_SM3 | INVALID_LEN | ERR_MSG)) +#define FW_ERROR_SM3_HMAC_INVALID_LEN_KEY (FROM_FW | (ERROR_SM3_HMAC | INVALID_LEN | ERR_KEY)) +#define FW_ERROR_SM4_INVALID_VAL_OID (FROM_FW | (ERROR_SM4 | INVALID_LEN | ERR_OID_ALG)) +#define FW_ERROR_SM4_INVALID_LEN_KEY (FROM_FW | (ERROR_SM4 | INVALID_LEN | ERR_KEY)) +#define FW_ERROR_SM4_INVALID_SEL_KEY (FROM_FW | (ERROR_SM4 | INVALID_SEL | ERR_KEY)) +#define FW_ERROR_SM4_INVALID_LEN_MSG (FROM_FW | (ERROR_SM4 | INVALID_LEN | ERR_MSG)) +#define FW_ERROR_AES_IP_BUSY (FROM_FW | (ERROR_AES | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_SM4_IP_BUSY (FROM_FW | (ERROR_SM4 | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_SM3_IP_BUSY (FROM_FW | (ERROR_SM3 | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_HASH_IP_BUSY (FROM_FW | (ERROR_SHA | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_TRNG_IP_BUSY (FROM_FW | (ERROR_RNG | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_PKA_IP_BUSY (FROM_FW | (ERROR_PKA | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_KM_IP_BUSY (FROM_FW | (ERROR_KM | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_SWDT1_IP_BUSY (FROM_FW | (ERROR_SWDT1 | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_SWDT2_IP_BUSY (FROM_FW | (ERROR_SWDT2 | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_FEEDER_IP_BUSY (FROM_FW | (ERROR_FEEDER | INVALID_STATUS | ERR_BUSY)) +#define FW_ERROR_INVALID_FUNCID00 (FROM_FW | (ERR_MB_CMD | INVALID_FUNCID00)) +#define FW_ERROR_INVALID_FUNCID01 (FROM_FW | (ERR_MB_CMD | INVALID_FUNCID01)) +#define FW_ERROR_INVALID_FUNCID02 (FROM_FW | (ERR_MB_CMD | INVALID_FUNCID02)) +#define FW_ERROR_INVALID_FUNCID03 (FROM_FW | (ERR_MB_CMD | INVALID_FUNCID03)) +#define FW_ERROR_EXECUTION_ORDER (FROM_FW | (ERR_MB_CMD | INVALID_ORDER)) + +// Secure Storage +#define ERROR_SSTORAGE_INVALID_SLOT_INDEX (0x00F1A1D1) +#define ERROR_SSTORAGE_INVALID_DATA_LEN (0x00F2A1D1) +#define ERROR_SSTORAGE_INVALID_TYPE (0x00F3A1D1) +#define ERROR_SSTORAGE_DATA_INVALID_DATA_LEN (0x0002A1D1) +#define ERROR_SSTORAGE_CERT_INVALID_DATA_LEN (0x0003A2D1) +#define ERROR_SSTORAGE_KEY_INVALID_DATA_LEN (0x0004A3D1) +#define ERROR_SSTORAGE_KEY_INVALID_KEY_LEN (0x0005A3D1) +#define ERROR_SSTORAGE_KEY_INVALID_KEY_TYPE (0x0006A3D1) +#define ERROR_SSTORAGE_FACTORYKEY_PBKEY_INVALID_DATA_LEN (0x0007A2D1) +#define ERROR_SSTORAGE_WRITE (0x0008A2D1) +#define ERROR_SSTORAGE_READ (0x0008A2D1) +#define ERROR_SSTORAGE_SFS_FOPEN (0x0009A2D1) +#define ERROR_SSTORAGE_SFS_FSEEK (0x000AA2D1) +#define ERROR_SSTORAGE_SFS_FREAD (0x000BA2D1) +#define ERROR_SSTORAGE_SFS_FWRITE (0x000CA2D1) + +#if 0 + +// SM4 +#define ERROR_SM4_INVALID_BLOCK_LEN (0x000134D1) +#define ERROR_SM4_INVALID_RSP_BLOCK_LEN (0x000234D1) +#define ERROR_SM4_INVALID_MSG_LEN (0x000334D1) +#define ERROR_SM4_INVALID_MODE (0x000434D1) +#define ERROR_SM4_INVALID_KEY_LEN (0x000534D1) +#define ERROR_SM4_INVALID_INDEX (0x000834D1) + +// Hash +#define ERROR_HASH_INVALID_MODE (0x000131D1) +#define ERROR_HASH_INVALID_BLOCK_LEN (0x000231D1) +#define ERROR_HASH_INVALID_MSG_LEN (0x000331D1) + +// HMAC +#define ERROR_HMAC_INVALID_MODE (0x000132D1) +#define ERROR_HMAC_INVALID_KEY_LEN (0x000232D1) +#define ERROR_HMAC_INVALID_BLOCK_LEN (0x000332D1) +#define ERROR_HMAC_INVALID_INDEX (0x000432D1) +#define ERROR_HMAC_INVALID_RSP_BLOCK_LEN (0x000532D1) + +// SM3 +#define ERROR_SM3_INVALID_MODE (0x000133D1) +#define ERROR_SM3_INVALID_BLOCK_LEN (0x000233D1) +#define ERROR_SM3_INVALID_MSG_LEN (0x000333D1) + +// DH +#define ERROR_DH_INVALID_PRIME_LEN (0x000125D1) +#define ERROR_DH_INVALID_PUBKEY_LEN (0x000225D1) +#define ERROR_DH_INVALID_PRIVATEKEY_LEN (0x000525D1) +#define ERROR_DH_INVALID_GENERATOR_LEN (0x000325D1) +#define ERROR_DH_INVALID_PRIME (0x000425D1) +#define ERROR_DH_INVALID_PUBKEY (0x000525D1) +#define ERROR_DH_INVALID_GENERATOR (0x000625D1) + +// ECDSA +#define ERROR_ECDSA_INVALID_MSG_LEN (0x000111D1) +#define ERROR_ECDSA_INVALID_SIGNATURE_LEN (0x000311D1) +#define ERROR_ECDH_INVALID_PUBKEY_LEN (0x000411D1) +#define ERROR_ECDH_INVALID_PUBKEY (0x000511D1) +#define ERROR_ECDH_INVALID_PRIVKEY_LEN (0x000611D1) +#define ERROR_ECDH_INVALID_PRIVKEY (0x000711D1) +// RSA +#define ERROR_RSA_INVALID_CIPHER_LEN (0x000151D1) +#define ERROR_RSA_INVALID_MSG_LEN (0x000251D1) +#define ERROR_RSA_INVALID_SIGN_LEN (0x000351D1) +#define ERROR_RSA_INVALID_PAD_SELECTION (0x000451D1) +#define ERROR_RSA_INVALID_PUKEY (0x000551D1) +#define ERROR_RSA_INVALID_PRIVKEY (0x000651D1) + +// RNG +#define ERROR_RNG_INVALID_RANDOM_REQUEST (0x000161D1) + +// Common +#define ERROR_SSKeyID_InputID_MISSMATCH (0x000171D1) +#define ERROR_INVALID_OID (0x000271D1) + +// System Function +#define ERROR_SYSTEM_INVALID_DATA_LEN (0x000201D1) +#define ERROR_SYSTEM_MAILBOX_BUSY (0x000100D1) + +// Error from FW + +#define FW_ERROR_ISP_INVALID_FUNCID00 (0x801000F1) +#define FW_ERROR_ISP_INVALID_FUNCID01 (0x801100F1) +#define FW_ERROR_ISP_INVALID_FUNCID02 (0x801200F1) +#define FW_ERROR_ISP_INVALID_FUNCID03 (0x801300F1) +#define FW_ERROR_ISP_INVALID_DATASIZE (0x801400F1) +#define FW_ERROR_ISP_FW_BODYSIZE (0x801500F1) +#define FW_ERROR_ISP_FW_ROLLBACK_CNT (0x801600F1) +#define FW_ERROR_ISP_FW_INVALID_PUBLICKEY (0x801700F1) +#define FW_ERROR_ISP_RESTORE_INTEGRITY_FAIL (0x801800F1) +#define FW_ERROR_ISP_IP_BUSY (0x801900F1) +#define FW_ERROR_ISP_SRAM_CMD_NOT_SUPPORTED (0x801A00F1) + +#define FW_ERROR_INVALID_FUNCTION (0x000100f1) +#define FW_ERROR_FW_VERIFY (0x001400f1) +#define FW_ERROR_RESTORE_FAIL (0x001800f1) +#define FW_ERROR_IP_BUSY (0x001900f1) +#define FW_ERROR_INVALID_OID (0x003000f1) +#define FW_ERROR_INVALID_INPUT (0x003400f1) +#define FW_ERROR_INPUT_SETTING (0x004000f1) +#define FW_ERROR_PRNG (0x005000f1) +#define FW_FAIL_INVALID_SIGNATURE (0x006000f1) +#define FW_FAIL_INFINITY_POINT (0x006100f1) +#define FW_FAIL_NOT_ON_ECC_CURVE (0x006200f1) + +// SRAM error +#define FW_ERROR_INVALID_EXEC_ORDER (0x80AF00F1) +#define FW_ERROR_OVER_VALID_RSA_MSGLEN (0x803500F1) +#define FW_ERROR_INVALID_RSA_MODLEN (0x803600F1) +#define FW_ERROR_Input_Public_is_not_odd (0x803700F1) +#define FW_ERROR_OVER_VALID_RSA_Saltlen (0x803800F1) +#define FW_ERROR_NO_PUKEY (0x803900F1) +#define FW_FAIL_OVER_MR_TRIALS (0x805600F1) +#define FW_FAIL_OVER_DH_RETRIALS (0x805600F1) +#define FW_FAIL_OVER_ECC_RETRIALS (0x805600F1) +#define FW_FAIL_NO_OUTPUT_KEY (0x805700F1) +#define FW_FAIL_OVER_GEN_RETRIALS (0x805800F1) +#define FW_ERROR_INVALID_RSASIGNATURE_0xBC (0x806400F1) +#define FW_ERROR_INVALID_RSASIGNATURE_lsb (0x806500F1) +#define FW_ERROR_INVALID_RSANONZERO_PS (0x806600F1) +#define FW_ERROR_INVALID_RSADB_SPLITTER (0x806700F1) +#define FW_ERROR_INVALID_SIGNATURE_BLEN (0x806800F1) +#define FW_ERROR_INVALID_CIPHER (0x806900F1) +#define FW_ERROR_INVALID_SEQUENCE (0x80ff00F1) +#define FW_ERROR_DER2INT_PARSE (0x80fe00F1) +#define FW_ERROR_AES_INVALID_KEYSEL (0x80D000F1) +#define FW_ERROR_AES_INVALID_KEY_LEN (0x80D100F1) +#define FW_ERROR_AES_INVALID_DIR_MODE (0x80D200F1) +#define FW_ERROR_AES_INVLIAD_SWAP (0x80D300F1) +#define FW_ERROR_AES_INVALID_MODE (0x80D400F1) +#define FW_ERROR_AES_INVALID_TAG (0x80D500F1) +#define FW_ERROR_AES_INVALID_BLOCK_LEN (0x80D600F1) +#define FW_ERROR_AES_KM_BUSY (0x80D700F1) +#define FW_ERROR_AES_KM_INIT (0x80D800F1) +#define FW_ERROR_SSTORAGE_DATA_INVALID_SLOT_INDEX (0x80E100F1) +#define FW_ERROR_SSTORAGE_CERT_INVALID_SLOT_INDEX (0x80E200F1) +#define FW_ERROR_SSTORAGE_KEY_INVALID_KEY_LEN (0x80E300F1) +#define FW_ERROR_SSTORAGE_KEY_INVALID_MODE (0x80E400F1) +#define FW_ERROR_SSTORAGE_INVALID_DATA_TYPE (0x80E500F1) +#define FW_ERROR_SSTORAGE_KEY_INVALID_KEYTYPE (0x80E600F1) +#define FW_ERROR_SSTORAGE_KEY_INVALID_SLOT_INDEX (0x80E700F1) +#define FW_ERROR_SSTORAGE_FACTORYKEY_INVALID_HMAC (0x80E800F1) +#define FW_ERROR_SSTORAGE_FACTORYKEY_INVALID_ENCODING (0x80E900F1) +#define FW_ERROR_SSTORAGE_FACTORYKEY_INVALID_KEYTYPE (0x80EA00F1) +#define FW_ERROR_RNG_INVALID_LEN (0x80f100F1) +#define FW_ERROR_KEYGEN_INVALID_KEYLEN (0x80f200F1) +#define FW_ERROR_PKA_IP_BUSY (0x80B100F1) +#define FW_ERROR_HASH_IP_BUSY (0x80B200F1) +#define FW_ERROR_PRNG_IP_BUSY (0x80B300F1) +#endif + +#endif /* SSS_DRIVER_ERROR_H */ diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.c b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.c new file mode 100644 index 0000000000..9d4e12f347 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 Files ********************************************/ +#include "sss_driver_error.h" +#include "sss_driver_rng.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +/*! @fn sss_generate_random(unsigned int *random, unsigned int wlen) + * @ingroup SECURITY_SSS + * @brief rng function + * @version v0.50 : 2016.8.13 Init. release version + * @version v0.01 : 2018.01.13 Modifyh for S111 SRAM code + * @param[out] random : array of random number + * @param[in] wlen : word length of random number to be generated + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int sss_generate_random(stOCTET_STRING *pstRandom, unsigned int request_byte_len) +{ + + unsigned int ret; + + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 1 : generate random + ret = mb_generate_random_number(pstRandom, request_byte_len); + + return ret; +} + + +/*! + * @ingroup SECURITY_SSS + * @brief rng function + * @version v0.50 : 2016.8.13 Init. release version + * @version v0.51 : 2018.01.13 Modifyh for S111 SRAM code + * @param[out] random : array of random number + * @param[in] wlen : word length of random number to be generated + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int sss_generate_rawrandom(stOCTET_STRING *pstRandom, unsigned int request_byte_len) +{ + + unsigned int ret; + + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 1 : generate random + ret = mb_generate_raw_random(pstRandom, request_byte_len); + + return ret; +} + + + +/*! + * @ingroup SECURITY_SSS + * @brief rng function + * @version v0.50 : 2016.8.13 Init. release version + * @version v0.51 : 2018.01.13 Modifyh for S111 SRAM code + * @param[out] random : array of random number + * @param[in] wlen : word length of random number to be generated + * @retval SUCCESS : Success + * @retval Others(!=0) : fail - error from sub-function + */ +unsigned int sss_KAT_RNG(void) +{ + + unsigned int ret; + + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 1 : call KAT + ret = mb_KAT_RNG(); + + return ret; +} + + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.h new file mode 100644 index 0000000000..088bc32491 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_rng.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SSS_DRIVER_RNG_H +#define SSS_DRIVER_RNG_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" +#include "mb_cmd_rng.h" +#include "mb_cmd_system.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +unsigned int sss_generate_random(stOCTET_STRING *pstRandom, unsigned int request_byte_len); +unsigned int sss_generate_rawrandom(stOCTET_STRING *pstRandom, unsigned int request_byte_len); +unsigned int sss_KAT_RNG(void); + +#endif /* SSS_DRIVER_RNG_H */ diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.c b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.c new file mode 100644 index 0000000000..46ceac32a0 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.c @@ -0,0 +1,196 @@ +/**************************************************************************/ +/* Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. */ +/* */ +/* -INSTRUCTIONS- */ +/* THIS SOFTWARE IS A CONFIDENTIAL STUFFS AND PROPRIETARY OF SAMSUNG ELEC */ +/* TRONICS CO.,LTD. SO YOU SHALL NOT DISCLOSE THIS SOFTWARE OTHER COMPANY */ +/* OR PERSONS WITHOUT PERMISSION OF SAMSUNG AND SHALL USE THIS SOFTWARE */ +/* ONLY IN ACCORDANCE WITH THE LICENSE AGREEMENT OF SAMSUNG. */ +/* SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY */ +/* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED */ +/* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */ +/* PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE LIABLE FOR ANY */ +/* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR */ +/* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ +/**************************************************************************/ + +/*************** Include Files ********************************************/ +#include "sss_driver_error.h" +#include "sss_driver_sha2.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + + +int sss_SHA2_256( + const stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest) +{ + + int ret = FAIL; + + stOCTET_STRING stHASH_Input; + unsigned int object_id; + unsigned int block_byte_len; + + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 0 : Check validity of parameter "object_id" +#if 0 + if (pstMessage->u32DataByteLen == 0) { + return ERROR_HASH_INVALID_LEN_MSG; + } +#endif + + //! assign hash_byte_len to compare returned result from sss_fw after hash operation + object_id = OID_SHA2_256; + block_byte_len = 64; + + //! step 1 : set message length parameter to SSS + ret = mb_hash_init(pstMessage, object_id); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 2 : set message block to SSS + stHASH_Input.pu08Data = pstMessage->pu08Data; + stHASH_Input.u32DataByteLen = pstMessage->u32DataByteLen; + + ret = mb_hash_update(&stHASH_Input, block_byte_len); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 3 : get hash result from SSS + ret = mb_hash_final(&stHASH_Input, pstDigest); + + return ret; +} + + + +int sss_SHA2_384( + const stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest) +{ + + int ret = FAIL; + + stOCTET_STRING stHASH_Input; + unsigned int object_id; + unsigned int block_byte_len; + + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 0 : Check validity of parameter "object_id" +#if 0 + if (pstMessage->u32DataByteLen == 0) { + return ERROR_HASH_INVALID_LEN_MSG; + } +#endif + + //! assign hash_byte_len to compare returned result from sss_fw after hash operation + object_id = OID_SHA2_384; + block_byte_len = 128; + + //! step 1 : set message length parameter to SSS + ret = mb_hash_init(pstMessage, object_id); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 2 : set message block to SSS + stHASH_Input.pu08Data = pstMessage->pu08Data; + stHASH_Input.u32DataByteLen = pstMessage->u32DataByteLen; + + ret = mb_hash_update(&stHASH_Input, block_byte_len); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 3 : get hash result from SSS + ret = mb_hash_final(&stHASH_Input, pstDigest); + + return ret; +} + + + +int sss_SHA2_512( + const stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest) +{ + + int ret = FAIL; + + stOCTET_STRING stHASH_Input; + unsigned int object_id; + unsigned int block_byte_len; + + //! step 0 : clear Mailbox + ret = mb_system_clear(CLEAR_TYPE_MAILBOX); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 0 : Check validity of parameter "object_id" +#if 0 + if (pstMessage->u32DataByteLen == 0) { + return ERROR_HASH_INVALID_LEN_MSG; + } +#endif + + //! assign hash_byte_len to compare returned result from sss_fw after hash operation + object_id = OID_SHA2_512; + block_byte_len = 128; + + //! step 1 : set message length parameter to SSS + ret = mb_hash_init(pstMessage, object_id); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 2 : set message block to SSS + stHASH_Input.pu08Data = pstMessage->pu08Data; + stHASH_Input.u32DataByteLen = pstMessage->u32DataByteLen; + + ret = mb_hash_update(&stHASH_Input, block_byte_len); + + if (ret != SSSR_SUCCESS) { + return ret; + } + + //! step 3 : get hash result from SSS + ret = mb_hash_final(&stHASH_Input, pstDigest); + + return ret; +} + + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.h new file mode 100644 index 0000000000..b4051c406f --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_sha2.h @@ -0,0 +1,135 @@ +/**************************************************************************/ +/* Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. */ +/* */ +/* -INSTRUCTIONS- */ +/* THIS SOFTWARE IS A CONFIDENTIAL STUFFS AND PROPRIETARY OF SAMSUNG ELEC */ +/* TRONICS CO.,LTD. SO YOU SHALL NOT DISCLOSE THIS SOFTWARE OTHER COMPANY */ +/* OR PERSONS WITHOUT PERMISSION OF SAMSUNG AND SHALL USE THIS SOFTWARE */ +/* ONLY IN ACCORDANCE WITH THE LICENSE AGREEMENT OF SAMSUNG. */ +/* SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY */ +/* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED */ +/* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */ +/* PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE LIABLE FOR ANY */ +/* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR */ +/* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ +/**************************************************************************/ + +#ifndef SSS_DRIVER_SHA2_H +#define SSS_DRIVER_SHA2_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" +#include "mb_cmd_hash.h" +#include "mb_cmd_system.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +/*! + * @brief SHA2-256 with normal mode + * @param[in] pstMessage pointer of struct for Message + + Name Description Variables + pu08Data array of Data + u32DataByteLen Byte length of Data (0< x < 2^32) + + * @param[out] pstDigest pointer of struct for Digest + + Name Description Variables + pu08Data array of Data + u32DataByteLen Byte length of Data 32 + + * @return + + Error Code Description + SSSR_SUCCESS Function operates normally + ERROR_SHA_INVALID_VAL_OID_ALG + ERROR_SHA_INVALID_LEN_MSG + + * @author kitak Kim (kitak81.kim@samsung.com) + * @version V0.00 + + Version Date Person Description + V0.00 2017.01.15 kitak Initial Version + */ +int sss_SHA2_256( + const stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest); + +/*! + * @brief SHA2-384 with normal mode + * @param[in] pstMessage pointer of struct for Message + + Name Description Variables + pu08Data array of Data + u32DataByteLen Byte length of Data (0< x < 2^32) + + * @param[out] pstDigest pointer of struct for Digest + + Name Description Variables + pu08Data array of Data + u32DataByteLen Byte length of Data 48 + + * @return + + Error Code Description + SSSR_SUCCESS Function operates normally + ERROR_SHA_INVALID_VAL_OID_ALG + ERROR_SHA_INVALID_LEN_MSG + + * @author kitak Kim (kitak81.kim@samsung.com) + * @version V0.00 + + Version Date Person Description + V0.00 2017.01.15 kitak Initial Version + V0.01 2018.01.09 kitak Modify for S111 SRAM code + */ +int sss_SHA2_384( + const stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest); + +/*! + * @brief SHA2-512 with normal mode + * @param[in] pstMessage pointer of struct for Message + + Name Description Variables + pu08Data array of Data + u32DataByteLen Byte length of Data (0< x < 2^32) + + * @param[out] pstDigest pointer of struct for Digest + + Name Description Variables + pu08Data array of Data + u32DataByteLen Byte length of Data 64 + + * @return + + Error Code Description + SSSR_SUCCESS Function operates normally + ERROR_SHA_INVALID_VAL_OID_ALG + ERROR_SHA_INVALID_LEN_MSG + + * @author kitak Kim (kitak81.kim@samsung.com) + * @version V0.00 + + Version Date Person Description + V0.00 2017.01.15 kitak Initial Version + V0.01 2018.01.09 kitak Modify for S111 SRAM code + */ +int sss_SHA2_512( + const stOCTET_STRING *pstMessage, + stOCTET_STRING *pstDigest); + +#endif /* ISP_DRIVER_SHA2_H */ + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.c b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.c new file mode 100644 index 0000000000..850c001bff --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.c @@ -0,0 +1,679 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 Files ********************************************/ +#include "sss_driver_util.h" +#include "sss_map.h" +#include "sss_driver_error.h" + + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +/*! @fn _sss_check_oid(u32 inputoid, u32 algorithm) + * @ingroup Util + * @brief Check valid oid according to algorithm + * @version v0.01 : 2016 + * @version v0.02 : 2018.01.04 Modify for S111 SRAM code + * @param[in] inputoid + * @param[in] algorithm + * @retval SUCCESS : success + */ +int _sss_check_oid(u32 inputoid, u32 algorithm) +{ + + u32 index = 0; + + u32 list_max = 0; + + u32 *pu32_list = 0; + + u32 OIDLIST_MHAC[OIDMAX_HMAC] = { + + OID_HMAC_SHA1_160, + OID_HMAC_SHA2_256, OID_HMAC_SHA2_384, OID_HMAC_SHA2_512, + }; + + u32 OIDLIST_HASH[OIDMAX_HASH] = { + + OID_SHA1_160, + OID_SHA2_256, OID_SHA2_384, OID_SHA2_512, + OID_SHA3_224, OID_SHA3_256, OID_SHA3_384, OID_SHA3_512, + }; + + u32 OIDLIST_DH[OIDMAX_DH] = { + + OID_DH_R5114_1024_160, OID_DH_R5114_2048_224, OID_DH_R5114_2048_256, + OID_DH_R2409_1024, //IKE + OID_DH_R3526_2048, + OID_DH_R5054_3072, OID_DH_R5054_4096 + }; + + u32 OIDLIST_ECC[OIDMAX_ECC] = { + + OID_ECC_BP192, OID_ECC_BP224, OID_ECC_BP256, OID_ECC_BP384, OID_ECC_BP512, + OID_ECC_P192, OID_ECC_P224, OID_ECC_P256, OID_ECC_P384, OID_ECC_P521, + }; + + u32 OIDLIST_RSA[OIDMAX_RSA] = { + + OID_RSA_1024, OID_RSA_2048, + }; + + u32 OIDLIST_ECDSA[OIDMAX_ECDSA] = { + + OID_ECDSA_BP192_SHA1_160, OID_ECDSA_BP192_SHA2_256, OID_ECDSA_BP192_SHA2_384, OID_ECDSA_BP192_SHA2_512, + OID_ECDSA_BP224_SHA1_160, OID_ECDSA_BP224_SHA2_256, OID_ECDSA_BP224_SHA2_384, OID_ECDSA_BP224_SHA2_512, + OID_ECDSA_BP256_SHA1_160, OID_ECDSA_BP256_SHA2_256, OID_ECDSA_BP256_SHA2_384, OID_ECDSA_BP256_SHA2_512, + OID_ECDSA_BP384_SHA1_160, OID_ECDSA_BP384_SHA2_256, OID_ECDSA_BP384_SHA2_384, OID_ECDSA_BP384_SHA2_512, + OID_ECDSA_BP512_SHA1_160, OID_ECDSA_BP512_SHA2_256, OID_ECDSA_BP512_SHA2_384, OID_ECDSA_BP512_SHA2_512, + OID_ECDSA_P192_SHA1_160, OID_ECDSA_P192_SHA2_256, OID_ECDSA_P192_SHA2_384, OID_ECDSA_P192_SHA2_512, + OID_ECDSA_P224_SHA1_160, OID_ECDSA_P224_SHA2_256, OID_ECDSA_P224_SHA2_384, OID_ECDSA_P224_SHA2_512, + OID_ECDSA_P256_SHA1_160, OID_ECDSA_P256_SHA2_256, OID_ECDSA_P256_SHA2_384, OID_ECDSA_P256_SHA2_512, + OID_ECDSA_P384_SHA1_160, OID_ECDSA_P384_SHA2_256, OID_ECDSA_P384_SHA2_384, OID_ECDSA_P384_SHA2_512, + OID_ECDSA_P521_SHA1_160, OID_ECDSA_P521_SHA2_256, + OID_ECDSA_P521_SHA2_384, OID_ECDSA_P521_SHA2_512, + }; + + switch (algorithm) { + + case SSS_HMAC: + + list_max = OIDMAX_HMAC; + + pu32_list = (u32 *) OIDLIST_MHAC; + + break; + + case SSS_HASH: + + list_max = OIDMAX_HASH; + + pu32_list = (u32 *) OIDLIST_HASH; + + break; + + case SSS_DH: + + list_max = OIDMAX_DH; + + pu32_list = (u32 *) OIDLIST_DH; + + break; + + case SSS_ECDH: + + list_max = OIDMAX_ECC; + + pu32_list = (u32 *) OIDLIST_ECC; + + break; + + case SSS_RSA: + + list_max = OIDMAX_RSA; + + pu32_list = (u32 *) OIDLIST_RSA; + + break; + + case SSS_ECDSA: + + list_max = OIDMAX_ECDSA; + + pu32_list = (u32 *) OIDLIST_ECDSA; + + break; + + default: + + return ERROR_INVALID_VAL_OID; + + }; + + index = 0; + + do { + + if (inputoid == *(pu32_list + index)) { + break; + } + //case for RSA oid & ECDH + if (inputoid == (*(pu32_list + index) + 0x10)) { + break; + } + + index++; + + if (index == list_max) { + + return ERROR_INVALID_VAL_OID; + + } + + } while (index < list_max); + + return SSSR_SUCCESS; +} + +/*! @fn int _sss_is_zero(const u32* pu32Src, u32 u32Size) + * @ingroup Util + * @brief Check zero array + * @version v0.10 : 2017.01.05 Init. + * @version v0.11 : 2018.01.04 Modify for S111 SRAM code + * @param[in] pu32Src + * - type : const u32* + * - Memory Address for the first parameter + * @param[in] u32Size + * - type : u32 + * - the size of memory to be compared + * @retval SUCCESS : success + * @retval 1 : fail + */ +#if 0 +int _isp_is_zero(const u32 *pu32Src, u32 u32Size) +{ + + u32 i = 0; + + u32 u32CompareFlag = 0; + + for (i = 0; i < u32Size; i++) { + + u32CompareFlag += (pu32Src[i] != 0x00) ? 0 : 1; + + } + + if ((i == u32CompareFlag) && (u32Size == u32CompareFlag)) { + + // All variables are zero + return 0; + + } + + else { + + // some variables are not zero + return 1; + + } +} + +#else /* + */ +int _sss_is_zero(const u08 *pu08Src, u32 u32ByteLen) +{ + + u32 i = 0; + + u32 u32CompareFlag = 0; + + for (i = 0; i < u32ByteLen; i++) { + + u32CompareFlag += (pu08Src[i] != 0x00) ? 0 : 1; + + } + + if ((i == u32CompareFlag) && (u32ByteLen == u32CompareFlag)) { + + // All variables are zero + return SSSR_SUCCESS; + + } + + else { + + // some variables are not zero + return SSSR_FAIL; + + } +} + +#endif /* + */ +int _sss_is_valid(const u08 *pu08Src, u32 u32ByteLen) +{ + + int ret = SSSR_FAIL; + + if ((u32ByteLen != 0) && ((pu08Src[0] & 0xC0) != 0)) { + + ret = SSSR_SUCCESS; + + } + + return ret; +} + +/*! + * @brief Function to Convert Octet-String to Mailbox + * @param[in] pstOSSrc Octet-String Source + * @param[in] pu32Dst Destination Address + * @param[in] u32RequestByteLen Byte length to be copied + * @return N/A + + * @author Kiseok Bae (kiseok.bae@samsung.com) + * @version V0.00 + + Version Date Person Description + V0.00 2017.06.17 kiseok Initial Version + V0.01 2018.01.04 kitak Modify for S111 SRAM code + */ +int _sss_BN_to_MB(const stBIG_NUM *pstOSSrc, u32 *pu32Dst, u32 u32RequestByteLen) +{ + + volatile u32 u32Tmp; + + int Index; + + int i = pstOSSrc->u32DataByteLen; + + u08 *pu08Src = pstOSSrc->pu08Data; + + //! Step 1. Check valid length + if (u32RequestByteLen > 256) { + return SSSR_FAIL; + } + + if (i > (int)u32RequestByteLen) { + i = u32RequestByteLen; + } + + //! Step 2. Define Copy word length + Index = CEIL_BY_WORD(u32RequestByteLen) - 1; + + //! Step 3. Data Copy + while (Index >= 0) { + + //! - set default is zero + u32Tmp = 0; + + //! - define update value + if (i >= 4) { + + u32Tmp = (((u32) pu08Src[i - 1]) << 24) + | (((u32) pu08Src[i - 2]) << 16) + | (((u32) pu08Src[i - 3]) << 8) + | ((u32) pu08Src[i - 4]); + + i -= 4; + + } else { + + switch (i) { + + case 3: + u32Tmp |= ((u32) pu08Src[i - 3]) << 8; + + case 2: + u32Tmp |= ((u32) pu08Src[i - 2]) << 16; + + case 1: + u32Tmp |= ((u32) pu08Src[i - 1]) << 24; + + default: + + i = 0; + + break; + + } + + } + + //! - update to destination + *(pu32Dst + Index) = u32Tmp; + + Index--; + + } + + return SSSR_SUCCESS; +} + +int _sss_MB_to_BN(stBIG_NUM *pstOSSDst, u32 *pu32Src, u32 u32RespondByteLen) +{ + + volatile u32 u32Tmp; + + int s32Index = 0; + + int s08Index = 0; + + u08 *pu08Dst = pstOSSDst->pu08Data; + + //! Step 1. Check valid output length + if (u32RespondByteLen > 256) { + + pstOSSDst->u32DataByteLen = 0; + + return SSSR_FAIL; + + } + + //! Step 2. Find zero bytes from MSB + //! find nonzeroword + do { + + u32Tmp = *(pu32Src + s32Index); + + s32Index++; + + } while (u32Tmp == 0x0); + + //! find nonzerobyte + while ((u32Tmp & 0xff) == 0x0) { + + u32Tmp = u32Tmp >> 8; + + s08Index++; + + } + + //! Step 2. Assign Dst length + if (pstOSSDst->u32DataByteLen == 0x0) { + + //! update length after zero unwrapping + pstOSSDst->u32DataByteLen = u32RespondByteLen - 4 * (s32Index - 1) - s08Index; + + } + + //! update length after zero unwrapping + //pstOSSDst->u32DataByteLen = u32RespondByteLen - 4*(s32Index-1) - s08Index; + + //! Step 3. Assign Dst length & copy length + s32Index = CEIL_BY_WORD(u32RespondByteLen) - 1; + + s08Index = pstOSSDst->u32DataByteLen; + + //! Step 4. Data Copy + while (s32Index >= 0) { + + //! - load 32bit data + u32Tmp = *(pu32Src + s32Index); + + //! - define update value + if (s08Index >= 4) { + + pu08Dst[s08Index - 4] = (u08)(u32Tmp); + + pu08Dst[s08Index - 3] = (u08)(u32Tmp >> 8); + + pu08Dst[s08Index - 2] = (u08)(u32Tmp >> 16); + + pu08Dst[s08Index - 1] = (u08)(u32Tmp >> 24); + + s08Index -= 4; + + } + + else { + + switch (s08Index) { + + case 3: + pu08Dst[s08Index - 3] = (u08)(u32Tmp >> 8); + + case 2: + pu08Dst[s08Index - 2] = (u08)(u32Tmp >> 16); + + case 1: + pu08Dst[s08Index - 1] = (u08)(u32Tmp >> 24); + + default: + + s08Index = 0; + + break; + + } + + } + + //! - update to destination + s32Index--; + + } + + return SSSR_SUCCESS; +} + +int _sss_OS_to_MB(const stOCTET_STRING *pstOSSrc, u32 *pu32Dst, u32 u32RequestByteLen) +{ + + volatile u32 u32Tmp; + int Index; + u08 *pu08Src = pstOSSrc->pu08Data; + + //! Step 1. Check valid length + if ((u32RequestByteLen > 256) || (pstOSSrc->u32DataByteLen < u32RequestByteLen)) { + return SSSR_FAIL; + } + + //! Step 2. Define Copy word length + Index = u32RequestByteLen; + + //! Step 3. Data Copy + //while(Index>=0) + while (Index > 0) { + + //! - set default is zero + u32Tmp = 0; + + //! - define update value + if (Index >= 4) { + + u32Tmp = (((u32) * (pu08Src + 3) << 24) + | ((u32) * (pu08Src + 2) << 16) + | ((u32) * (pu08Src + 1) << 8) + | (u32) * (pu08Src)); + + pu08Src += 4; + } + + else { + + switch (Index) { + + case 3: + u32Tmp |= ((u32) * (pu08Src + 2) << 16); + + case 2: + u32Tmp |= ((u32) * (pu08Src + 1) << 8); + + case 1: + u32Tmp |= ((u32) * (pu08Src)); + + default: + Index = 0; + break; + + } + + } + + //! - update to destination + *(pu32Dst++) = u32Tmp; + + Index -= 4; + + } + + return SSSR_SUCCESS; +} + + +int _sss_MB_to_OS(stOCTET_STRING *pstOSSDst, u32 *pu32Src, u32 u32RespondByteLen) +{ + + volatile u32 u32Tmp; + int Index; + u08 *pu08Dst = pstOSSDst->pu08Data; + + //! Step 1. Check valid length + if (u32RespondByteLen > 256) { + pstOSSDst->u32DataByteLen = 0; + return SSSR_FAIL; + } + + //! Step 2. Define Copy word length + pstOSSDst->u32DataByteLen = Index = u32RespondByteLen; + + //! Step 3. Data Copy + //while(Index>=0) + while (Index > 0) { + + //! - load 32bit data + u32Tmp = *(pu32Src++); + + //! - define update value + if (Index >= 4) { + *(pu08Dst) = (u08)(u32Tmp); + *(pu08Dst + 1) = (u08)(u32Tmp >> 8); + *(pu08Dst + 2) = (u08)(u32Tmp >> 16); + *(pu08Dst + 3) = (u08)(u32Tmp >> 24); + pu08Dst += 4; + } else { + + switch (Index) { + case 3: + *(pu08Dst + 2) = (u08)(u32Tmp >> 16); + case 2: + *(pu08Dst + 1) = (u08)(u32Tmp >> 8); + case 1: + *(pu08Dst) = (u08)(u32Tmp); + default: + Index = 0; + break; + } + } + //! - update to destination + Index -= 4; + } + + return SSSR_SUCCESS; +} + +/*! @fn _sss_memcpy_u08(u08* pu08Dst, u08* pu08Src, u32 u32Size) + * @ingroup Util + * @brief Memory Copy based on u08 + * @version v0.01 : 2015 + * @version v0.02 : 2018.01.04 Modify for S111 SRAM code + * @param pu08Dst [IN] + * - type : u08* + * - Memory Address for the destination + * @param pu08Src [IN] + * - type : const u08* + * - Memory Address for the destination + * @param u32Size [IN] + * - type : u32 + * - the size of memory to be compared + * @retval SUCCESS : success + */ +int _sss_memcpy_u08(u08 *pu08Dst, u08 *pu08Src, u32 u32Size) +{ + + u08 *pu08DstAddr; + + u08 *pu08SrcAddr; + + pu08DstAddr = pu08Dst; + + pu08SrcAddr = pu08Src; + + while (u32Size--) { + + *pu08DstAddr++ = *pu08SrcAddr++; + + } + + return 0; +} +/*! @fn _sss_memset_u08(u08* pu08Dst, const u08 u08Src, u32 u32Size) + * @ingroup Util + * @brief Memory Set using constant based on u08 + * @version v0.01 : 2015 + * @version v0.02 : 2018.01.04 Modify for S111 SRAM code + * @param pu08Dst [IN] + * - type : u08* + * - Memory Address for the destination + * @param u08Src [IN] + * - type : const u08 + * - constant value + * @param u32Size [IN] + * - type : u32 + * - the size of memory to be compared + * @retval SUCCESS : success + */ +int _sss_memset_u08(u08 *pu08Dst, const u08 u08Src, u32 u32Size) +{ + + while (u32Size--) { + + *pu08Dst++ = u08Src; + + } + + return 0; +} + +int _sss_memcpy_mailbox(u32 *pu32Dst, u32 *pu32Src, u32 u32Size_byte_len) +{ + volatile u32 u32Temp; + + // if ((u32Size_byte_len == 0) || (u32Size_byte_len > 256)) { + // return 1; + // } + + while (u32Size_byte_len >= 4) { + u32Temp = *(pu32Src++); + *(pu32Dst++) = u32Temp; + u32Size_byte_len -= 4; + } + + // taidong_161027 copy last block based on byte length + switch (u32Size_byte_len) { + + case 1: + *pu32Dst = (*pu32Dst & 0xFFFFFF00) ^ (*pu32Src & 0x000000FF); + break; + + case 2: + *pu32Dst = (*pu32Dst & 0xFFFF0000) ^ (*pu32Src & 0x0000FFFF); + break; + + case 3: + *pu32Dst = (*pu32Dst & 0xFF000000) ^ (*pu32Src & 0x00FFFFFF); + break; + } + + return 0; +} + diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.h new file mode 100644 index 0000000000..089d25dd8e --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_driver_util.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SSS_DRIVER_UTIL_H +#define SSS_DRIVER_UTIL_H + +/*************** Include Files ********************************************/ +#include "sss_common.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +#define SSS_HMAC (0x001) +#define SSS_HASH (0x002) +#define SSS_DH (0x003) +#define SSS_ECDH (0x004) +#define SSS_RSA (0x005) +#define SSS_ECDSA (0x006) + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + +int _sss_check_oid(u32 inputoid, u32 algorithm); + +int _sss_is_zero(const u08 *pu08Src, u32 u32ByteLen); +int _sss_is_valid(const u08 *pu08Src, u32 u32ByteLen); + +int _sss_MB_to_BN(stBIG_NUM *pstBNSDst, u32 *pu32Src, u32 u32RespondByteLen); +int _sss_BN_to_MB(const stBIG_NUM *pstBNSrc, u32 *pu32Dst, u32 u32RequestByteLen); +int _sss_OS_to_MB(const stOCTET_STRING *pstOSSrc, u32 *pu32Dst, u32 u32RequestByteLen); +int _sss_MB_to_OS(stOCTET_STRING *pstOSSDst, u32 *pu32Src, u32 u32RespondByteLen); + +int _sss_memcpy_u08(u08 *pu08Dst, u08 *pu08Src, u32 u32Size); +int _sss_memset_u08(u08 *pu08Dst, const u08 u08Src, u32 u32Size); +int _sss_memcpy_mailbox(u32 *pu32Dst, u32 *pu32Src, u32 u32Size_byte_len); + +#endif /* SSS_UTIL_H */ diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_map.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_map.h new file mode 100644 index 0000000000..e622107931 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_map.h @@ -0,0 +1,123 @@ +/**************************************************************************/ +/* Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. */ +/* */ +/* -INSTRUCTIONS- */ +/* THIS SOFTWARE IS A CONFIDENTIAL STUFFS AND PROPRIETARY OF SAMSUNG ELEC */ +/* TRONICS CO.,LTD. SO YOU SHALL NOT DISCLOSE THIS SOFTWARE OTHER COMPANY */ +/* OR PERSONS WITHOUT PERMISSION OF SAMSUNG AND SHALL USE THIS SOFTWARE */ +/* ONLY IN ACCORDANCE WITH THE LICENSE AGREEMENT OF SAMSUNG. */ +/* SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY */ +/* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED */ +/* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */ +/* PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE LIABLE FOR ANY */ +/* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR */ +/* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ +/**************************************************************************/ + +#ifndef SSS_MAP_H +#define SSS_MAP_H + +/*************** Include Files ********************************************/ + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +#define SSS_CMD_GET_INFO (0x101) +#define SSS_CMD_SUCCESS (0xA1) +#define SSS_CMD_FAIL (0xF1) + +#define SSS_SRAM_LOCK_EN (0x01) +#define SSS_DEBUG_LOCK_EN (0x08) + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ +///////////////////////////////////////////////////////// +// SSS Address in S5J_S100 and S5JT100 ////////////////// +///////////////////////////////////////////////////////// +#if defined(TARGET_S5JS100) +#define SSS_REG_BASE (0x83100000) +#define MAILBOX_BASE (0x83110000) +#define SSS_SRAM_BASE (0x83108000) +#define SSS_TRNG_BASE (0x83180000) +#endif + +#if defined(TARGET_S3JT100) +#define SSS_REG_BASE (0x400C0000) +#define MAILBOX_BASE (0x400E0000) +#define SSS_SRAM_BASE (0x400C8000) +#define SSS_TRNG_BASE (0x400C1400) +#endif + +///////////////////////////////////////////////////////// +// SSS MAP ////////////////////////////////////////////// +///////////////////////////////////////////////////////// +#define SSS_FEEDER_BASE (SSS_REG_BASE) +#define SSS_DATA_BASE (SSS_SRAM_BASE + 0x6F00) + +#define SSS_CM0_LP_CON (*(volatile unsigned int *)(SSS_FEEDER_BASE + 0x001C)) +#define SSS_LOW_POWER_MODE_EN (1<<0) +#define SSS_CM0_RESET (*(volatile unsigned int *)(MAILBOX_BASE + 0x0004)) +#define SSS_CM0_HRESET (1<<0) +#define SSS_CM0_SRAM_ACCESS_CONTROL (*(volatile unsigned int *)(MAILBOX_BASE + 0x0008)) +#define SSS_CM0_DEBUG_CONTROL (*(volatile unsigned int *)(MAILBOX_BASE + 0x0038)) + +#define SSS_MB_STATUS (*(volatile unsigned int *)(MAILBOX_BASE + 0x0000)) +#define SSS_CM0_BUSY (1<<0) +#define SSS_CTRL_FIELD_BASE (MAILBOX_BASE + 0x0100) +#define SSS_DATA_FIELD_BASE (MAILBOX_BASE + 0x0110) + +#define SSS_TRNG_CLKDIV (*(volatile unsigned int *)(SSS_REG_BASE + 0x1400)) +#define SSS_TRNG_STARTUP_CTRL (*(volatile unsigned int *)(SSS_REG_BASE + 0x144C)) +#define SSS_STARTUP_HTPASS (1<<0) +#define SSS_STARTUP_HTPASS_CLR (1<<0) +#define SSS_TRNG_CTRL (*(volatile unsigned int *)(SSS_REG_BASE + 0x1420)) +#define SSS_RNGEN (0x80000000) +#define SSS_TRNG_TEST_CTRL (*(volatile unsigned int *)(SSS_REG_BASE + 0x1440)) +#define SSS_HTEN (1<<1) +#define SSS_TRNG_TEST_DONE (*(volatile unsigned int *)(SSS_REG_BASE + 0x1460)) +#define SSS_HTDONE (1<<1) +#define SSS_KATDONE (1<<2) +#define SSS_TRNG_TEST_STAT (*(volatile unsigned int *)(SSS_REG_BASE + 0x1444)) +#define SSS_HTERR (1<<2) +#define SSS_KAT_PPERR (1<<3) +#define SSS_KAT_CRNGTERR (1<<4) +#define SSS_TRNG_FIFO_CTRL (*(volatile unsigned int *)(SSS_REG_BASE + 0x1450)) +#define SSS_GEN_1_BYTE (1) +#define SSS_GEN_2_BYTE (2) +#define SSS_GEN_32_BYTE (32) + + + +#if defined(TARGET_S5JS100) +#ifdef OTP_BANK +#define OTP_BASE (0x80000000) +#define SSS_ROOT_ENCRYPTION_KEY_BASE (OTP_BASE + 0x000) +#define SSS_ROOT_PRIVATE_KEY_BASE (OTP_BASE + 0x020) +#define SSS_FW_ENCRYPTION_KEY_BASE (OTP_BASE + 0x080) + +#define SSS_KM_DIAG_DISABLE (OTP_BASE + 0x0A0) +#define SSS_CM0_DEBUG_DISABLE (OTP_BASE + 0x0A4) +#define SSS_CM0_SRAM_BOOT_DISABLE (OTP_BASE + 0x0A8) +#define SSS_CM0_SRAM_READ_DISABLE (OTP_BASE + 0x0AC) +#define SSS_CM0_ANTI_ROLLBACK_COUNT (OTP_BASE + 0x0B0) +#define SSS_CM0_SECURE_BOOT_KEY_BASE (OTP_BASE + 0x0C0) +#define SSS_TRANSFER_KEY1_BASE (OTP_BASE + 0x100) +#define SSS_TRANSFER_KEY2_BASE (OTP_BASE + 0x110) +#define SSS_TRANSFER_KEY3_BASE (OTP_BASE + 0x120) +#define SSS_TRANSFER_KEY4_BASE (OTP_BASE + 0x130) + +#define PUF_KEY_BASE (OTP_BASE + 0x140) +#define PUF_KEY_VALID (OTP_BASE + 0x160) + +#define SSS_SW_POR (OTP_BASE + 0x200) +#endif //OTP_BANK +#endif //TARGET_S5JS100 + +#endif /* SSS_MAP_H */ diff --git a/targets/TARGET_Samsung/security_subsystem/drivers/sss_oid.h b/targets/TARGET_Samsung/security_subsystem/drivers/sss_oid.h new file mode 100644 index 0000000000..7f384704af --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/drivers/sss_oid.h @@ -0,0 +1,242 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SSS_OID_H +#define SSS_OID_H + + +/*************** Include Files ********************************************/ + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ + +/* + * OID LIST + */ +#define OIDMAX_AES (12) +#define OID_AES_ECB (0x00000008) +#define OID_AES_ECB_128 (0x00100008) +#define OID_AES_ECB_192 (0x00180008) +#define OID_AES_ECB_256 (0x00200008) +#define OID_AES_CBC (0x00000108) +#define OID_AES_CBC_128 (0x00100108) +#define OID_AES_CBC_192 (0x00180108) +#define OID_AES_CBC_256 (0x00200108) +#define OID_AES_CTR (0x00000208) +#define OID_AES_CTR_128 (0x00100208) +#define OID_AES_CTR_192 (0x00180208) +#define OID_AES_CTR_256 (0x00200208) +#define OID_AES_XTS (0x00000308) +#define OID_AES_XTS_128 (0x00100308) +#define OID_AES_XTS_256 (0x00200308) +#define OID_AES_CCM (0x00001008) +#define OID_AES_CCM_128 (0x00101008) +#define OID_AES_CCM_192 (0x00181008) +#define OID_AES_CCM_256 (0x00201008) +#define OID_AES_GCM (0x00001108) +#define OID_AES_GCM_128 (0x00101108) +#define OID_AES_GCM_192 (0x00181108) +#define OID_AES_GCM_256 (0x00201108) +#define OID_AES_CMAC (0x00001208) +#define OID_AES_CMAC_128 (0x00101208) +#define OID_AES_CMAC_192 (0x00181208) +#define OID_AES_CMAC_256 (0x00201208) + +#define OID_AES_ENCRYPT (0x00000000) +#define OID_AES_DECRYPT (0x01000000) + +#define OID_ENCRYPTION (0x00000000) +#define OID_DECRYPTION (0x01000000) + +#define OIDMAX_SM4 (1) +#define OID_SM4_ECB (0x00000009) +#define OID_SM4_ECB_128 (0x00100009) +#define OID_SM4_ENCRYPT (OID_AES_ENCRYPT) +#define OID_SM4_DECRYPT (OID_AES_DECRYPT) + +#define OIDMAX_HMAC (4) +#define OID_HMAC_SHA1_160 (0x00011100) +#define OID_HMAC_SHA2_224 (0x00012200) //NA +#define OID_HMAC_SHA2_256 (0x00012300) +#define OID_HMAC_SHA2_384 (0x00012400) +#define OID_HMAC_SHA2_512 (0x00012500) + +#define OIDMAX_HASH (8) +#define OID_SHA1_160 (0x00001100) +#define OID_SHA2_224 (0x00002200) //NA +#define OID_SHA2_256 (0x00002300) +#define OID_SHA2_384 (0x00002400) +#define OID_SHA2_512 (0x00002500) +#define OID_SHA3_224 (0x00003200) //NA +#define OID_SHA3_256 (0x00003300) //NA +#define OID_SHA3_384 (0x00003400) //NA +#define OID_SHA3_512 (0x00003500) //NA + +#define OIDMAX_HMACSM3 (1) +#define OID_HMAC_SM3_256 (0x01012300) + +#define OIDMAX_SM3 (1) +#define OID_SM3_256 (0x01002300) + +#define OIDMAX_DH (7) +#define OID_DH_R5114_1024_160 (0x00001151) +#define OID_DH_R5114_2048_224 (0x00003252) +#define OID_DH_R5114_2048_256 (0x00003352) +#define OID_DH_R2409_1024 (0x00001131) +#define OID_DH_R3526_2048 (0x00003332) +#define OID_DH_R5054_3072 (0x00004033) +#define OID_DH_R5054_4096 (0x00005034) + +#define OIDMAX_ECC (10) +#define OID_ECC_P192 (0x00000011) +#define OID_ECC_P224 (0x00000012) +#define OID_ECC_P256 (0x00000013) +#define OID_ECC_P384 (0x00000014) +#define OID_ECC_P521 (0x00000015) +#define OID_ECC_BP192 (0x00000051) +#define OID_ECC_BP224 (0x00000052) +#define OID_ECC_BP256 (0x00000053) +#define OID_ECC_BP384 (0x00000054) +#define OID_ECC_BP512 (0x00000055) +#define OID_ECC_25519 (0x00000093) + +#define OIDMAX_RSA (2) +#define OID_RSA_1024 (0x000000B1) +#define OID_RSA_2048 (0x000000B2) +#define OID_RSA_3072 (0x000000B3) +#define OID_RSA_4096 (0x000000B4) + +#define OIDMAX_ECDSA (40) +#define OID_ECDSA_BP192_SHA1_160 (OID_ECC_BP192|OID_SHA1_160) +#define OID_ECDSA_BP192_SHA2_256 (OID_ECC_BP192|OID_SHA2_256) +#define OID_ECDSA_BP192_SHA2_384 (OID_ECC_BP192|OID_SHA2_384) +#define OID_ECDSA_BP192_SHA2_512 (OID_ECC_BP192|OID_SHA2_512) +#define OID_ECDSA_BP224_SHA1_160 (OID_ECC_BP224|OID_SHA1_160) +#define OID_ECDSA_BP224_SHA2_256 (OID_ECC_BP224|OID_SHA2_256) +#define OID_ECDSA_BP224_SHA2_384 (OID_ECC_BP224|OID_SHA2_384) +#define OID_ECDSA_BP224_SHA2_512 (OID_ECC_BP224|OID_SHA2_512) +#define OID_ECDSA_BP256_SHA1_160 (OID_ECC_BP256|OID_SHA1_160) +#define OID_ECDSA_BP256_SHA2_256 (OID_ECC_BP256|OID_SHA2_256) +#define OID_ECDSA_BP256_SHA2_384 (OID_ECC_BP256|OID_SHA2_384) +#define OID_ECDSA_BP256_SHA2_512 (OID_ECC_BP256|OID_SHA2_512) +#define OID_ECDSA_BP384_SHA1_160 (OID_ECC_BP384|OID_SHA1_160) +#define OID_ECDSA_BP384_SHA2_256 (OID_ECC_BP384|OID_SHA2_256) +#define OID_ECDSA_BP384_SHA2_384 (OID_ECC_BP384|OID_SHA2_384) +#define OID_ECDSA_BP384_SHA2_512 (OID_ECC_BP384|OID_SHA2_512) +#define OID_ECDSA_BP512_SHA1_160 (OID_ECC_BP512|OID_SHA1_160) +#define OID_ECDSA_BP512_SHA2_256 (OID_ECC_BP512|OID_SHA2_256) +#define OID_ECDSA_BP512_SHA2_384 (OID_ECC_BP512|OID_SHA2_384) +#define OID_ECDSA_BP512_SHA2_512 (OID_ECC_BP512|OID_SHA2_512) + +#define OID_ECDSA_P192_SHA1_160 (OID_ECC_P192|OID_SHA1_160) +#define OID_ECDSA_P192_SHA2_256 (OID_ECC_P192|OID_SHA2_256) +#define OID_ECDSA_P192_SHA2_384 (OID_ECC_P192|OID_SHA2_384) +#define OID_ECDSA_P192_SHA2_512 (OID_ECC_P192|OID_SHA2_512) +#define OID_ECDSA_P224_SHA1_160 (OID_ECC_P224|OID_SHA1_160) +#define OID_ECDSA_P224_SHA2_256 (OID_ECC_P224|OID_SHA2_256) +#define OID_ECDSA_P224_SHA2_384 (OID_ECC_P224|OID_SHA2_384) +#define OID_ECDSA_P224_SHA2_512 (OID_ECC_P224|OID_SHA2_512) +#define OID_ECDSA_P256_SHA1_160 (OID_ECC_P256|OID_SHA1_160) +#define OID_ECDSA_P256_SHA2_256 (OID_ECC_P256|OID_SHA2_256) +#define OID_ECDSA_P256_SHA2_384 (OID_ECC_P256|OID_SHA2_384) +#define OID_ECDSA_P256_SHA2_512 (OID_ECC_P256|OID_SHA2_512) +#define OID_ECDSA_P384_SHA1_160 (OID_ECC_P384|OID_SHA1_160) +#define OID_ECDSA_P384_SHA2_256 (OID_ECC_P384|OID_SHA2_256) +#define OID_ECDSA_P384_SHA2_384 (OID_ECC_P384|OID_SHA2_384) +#define OID_ECDSA_P384_SHA2_512 (OID_ECC_P384|OID_SHA2_512) +#define OID_ECDSA_P521_SHA1_160 (OID_ECC_P521|OID_SHA1_160) +#define OID_ECDSA_P521_SHA2_256 (OID_ECC_P521|OID_SHA2_256) +#define OID_ECDSA_P521_SHA2_384 (OID_ECC_P521|OID_SHA2_384) +#define OID_ECDSA_P521_SHA2_512 (OID_ECC_P521|OID_SHA2_512) + +#define OIDMAX_RSASSA (8) +#define OID_RSASSA_PADDING_PKCS (0x01) +#define OID_RSASSA_PADDING_PSS (0x00) +#define OID_RSASSA_1024_SHA1_160 (OID_RSA_1024|OID_SHA1_160) +#define OID_RSASSA_1024_SHA2_256 (OID_RSA_1024|OID_SHA2_256) +#define OID_RSASSA_1024_SHA2_384 (OID_RSA_1024|OID_SHA2_384) +#define OID_RSASSA_1024_SHA2_512 (OID_RSA_1024|OID_SHA2_512) +#define OID_RSASSA_2048_SHA1_160 (OID_RSA_2048|OID_SHA1_160) +#define OID_RSASSA_2048_SHA2_256 (OID_RSA_2048|OID_SHA2_256) +#define OID_RSASSA_2048_SHA2_384 (OID_RSA_2048|OID_SHA2_384) +#define OID_RSASSA_2048_SHA2_512 (OID_RSA_2048|OID_SHA2_512) + +#define OIDMAX_RSAES (8) +#define OID_RSAES_PADDING_PKCS (0x01) +#define OID_RSAES_PADDING_OAEP (0x00) +#define OID_RSAES_1024_SHA1_160 (OID_RSA_1024|OID_SHA1_160) +#define OID_RSAES_1024_SHA2_256 (OID_RSA_1024|OID_SHA2_256) +#define OID_RSAES_1024_SHA2_384 (OID_RSA_1024|OID_SHA2_384) +#define OID_RSAES_1024_SHA2_512 (OID_RSA_1024|OID_SHA2_512) +#define OID_RSAES_2048_SHA1_160 (OID_RSA_2048|OID_SHA1_160) +#define OID_RSAES_2048_SHA2_256 (OID_RSA_2048|OID_SHA2_256) +#define OID_RSAES_2048_SHA2_384 (OID_RSA_2048|OID_SHA2_384) +#define OID_RSAES_2048_SHA2_512 (OID_RSA_2048|OID_SHA2_512) + + +/*************** Macros *****************************************/ +//ECC +#define GET_ECC_CURVE(OID) ((OID) & 0x07) +#define GET_ECC_ALG(OID) ((OID >> 4) & 0x0F) +#define Is_ECC_BP(OID) (OID & 0x40) + +//RSA +#define GET_RSA_Keyblen(OID) ((OID & 0xF) << 10) //1024 or 2048 +#define GET_RSA_KeyBytelen(OID) ((OID & 0xF) << 7) //128, 256 +#define GET_RSA_Type(OID) ((OID >> 4) & 0xF) //B(ENC) or C(SIGN) + +//Hash +#define GET_HASH_SIZE(OID) ((OID >> 8) & 0x07) +#define GET_HASH_ALG(OID) ((OID >> 12) & 0x0F) + +//HMAC +#define Is_HMAC_ALG(OID) ((OID >> 16) & 0x0F) + +//AES +#define GET_AES_MODE(OID) (OID & 0xffff) +#define GET_AES_SIZE(OID) ((OID >> 16) & 0xFF) +#define GET_ENC_DIRECTION(OID) ((OID >> 24) & 0x0F) + +//DH +#define IS_NOT_DHPARAM_R5114(OID) (((OID >> 4) & 0xf) ^ 0x5) +#define GET_DHPRIME_SIZE(OID) ((OID >> 12) & 0xf) +#define GET_DHORDER_SIZE(OID) ((OID >> 8) & 0xf) + + + +#define OIDMAX_MILENAGE (1) +#define OID_MILENAGE (0x00080000) +#define OID_F1 (0x01000000) +#define OID_F1S (0x02000000) +#define OID_F2 (0x03000000) +#define OID_F3 (0x04000000) +#define OID_F4 (0x05000000) +#define OID_F5 (0x06000000) +#define OID_F5S (0x07000000) +#define OID_MILENAGE_F1 (OID_MILENAGE | OID_F1) +#define OID_MILENAGE_F1S (OID_MILENAGE | OID_F1S) +#define OID_MILENAGE_F2 (OID_MILENAGE | OID_F2) +#define OID_MILENAGE_F3 (OID_MILENAGE | OID_F3) +#define OID_MILENAGE_F4 (OID_MILENAGE | OID_F4) +#define OID_MILENAGE_F5 (OID_MILENAGE | OID_F5) +#define OID_MILENAGE_F5S (OID_MILENAGE | OID_F5S) + + + +#endif /* SSS_OID_H */ diff --git a/targets/TARGET_Samsung/security_subsystem/sss_common.h b/targets/TARGET_Samsung/security_subsystem/sss_common.h new file mode 100644 index 0000000000..4a7d1c9c45 --- /dev/null +++ b/targets/TARGET_Samsung/security_subsystem/sss_common.h @@ -0,0 +1,161 @@ +/**************************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 SSS_COMMON_H +#define SSS_COMMON_H + +/*************** Include Files ********************************************/ +#include "sss_oid.h" + +/*************** Assertions ***********************************************/ + +/*************** Definitions / Macros *************************************/ +#define SUCCESS (0x00) +#define FAIL (0x01) + +#define SSSR_SUCCESS (0x00) +#define SSSR_FAIL (0x01) + +#define RSP_FAIL (0xF1) +#define RSP_SUCCESS (0xA1) + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define NULLPTR (void *)0 + + +///////////////////////////////////////////////////////// +// MACRO //////////////////////////////////////////////// +///////////////////////////////////////////////////////// +#define BIT(nbit) (0x1u << (nbit)) +#define SFR_BIT_SET(val, bit) ((val) |= (bit)) ///> 0)); \ + ((u08 *)(buf))[2] = ((u08)((dword) >> 8)); \ + ((u08 *)(buf))[1] = ((u08)((dword) >> 16)); \ + ((u08 *)(buf))[0] = ((u08)((dword) >> 24)); + +#define GET_DWORD_FROM_BBUF(buf) \ + (u32)( \ + ((((u08 *)(buf))[3]) << 0) | \ + ((((u08 *)(buf))[2]) << 8) | \ + ((((u08 *)(buf))[1]) << 16) | \ + ((((u08 *)(buf))[0]) << 24)) + +#define SWAP32(val) \ + (u32)( \ + (((val) & 0xff) << 24) | \ + (((val) & 0xff00) << 8) | \ + (((val) & 0xff0000) >> 8) | \ + (((val) & 0xff000000) >> 24) \ + ) + + +#define CEIL_16BYTE(val) (val&0xF) ? ((val&0xFFFFFFF0)+0x10) : (val) +#define CEIL_BY_WORD(val) (((val)+3)>>2) +#define CEIL_BY_16BYTE(val) (((val)+15)>>4) +//#define CEIL_BY_BYTE(bitval) (((bitval)+7)>>3) + + +/*************** New Data Types (Basic Data Types) ***********************/ + +/*************** New Data Types *******************************************/ +//! 8bits unsigned data type +typedef unsigned char u08; +//! 16bits unsigned data type +typedef unsigned short u16; +//! 32bits unsigned data type +typedef unsigned int u32; +//! 64bits unsigned data type +typedef unsigned long long u64; +//! CPU size bits unsigned data type +typedef unsigned int uwd; +//! 8bits signed data type +typedef char s08; +//! 16bits signed data type +typedef short s16; +//! 32bits signed data type +typedef int s32; +//! 64bits signed data type +typedef long long s64; +//! CPU size bits signed data type +typedef int swd; + +//! return error code +typedef u32 SSS_RV; + +/** + * @brief struct of OCTET String / length & data + */ +typedef struct _OS_st { + //! byte length of Data + u32 u32DataByteLen; + //! byte array of Data + u08 *pu08Data; +} stOCTET_STRING; + +/** + * @brief struct of BIGNUM String / length & data + */ +typedef stOCTET_STRING stBIG_NUM; + + + + + +/*************** Constants ************************************************/ + +/*************** Variable declarations ************************************/ + +/*************** Functions ***********************************************/ + + +#endif /* SSS_COMMON_H */ + diff --git a/targets/targets.json b/targets/targets.json index 0285830a65..31aae0a66c 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -14177,6 +14177,26 @@ "device_name": "STM32G071RBTx", "bootloader_supported": true }, + "S5JS100": { + "inherits": ["Target"], + "core": "Cortex-M7", + "supported_toolchains": ["GCC_ARM", "IAR", "ARMC6"], + "default_toolchain": "GCC_ARM", + "extra_labels": ["Samsung", "SIDK_S5JS100"], + "macros": ["CMSDK_CM7", "MBED_MPU_CUSTOM", "CMSIS_NVIC_VIRTUAL", "MBEDTLS_CONFIG_HW_SUPPORT"], + "device_has": [ + "INTERRUPTIN", + "PORTIN", + "PORTINOUT", + "PORTOUT", + "USTICKER", + "SERIAL", + "SLEEP", + "TRNG" + ], + "device_name": "S5JS100", + "release_versions": ["5"] + }, "__build_tools_metadata__": { "version": "1", "public": false diff --git a/tools/export/iar/iar_definitions.json b/tools/export/iar/iar_definitions.json index c6e7528dde..c9ec1bfab5 100644 --- a/tools/export/iar/iar_definitions.json +++ b/tools/export/iar/iar_definitions.json @@ -395,5 +395,9 @@ "OGChipSelectEditMenu": "TMPM4G9F15FG\tToshiba TMPM4G9F15FG", "GFPUCoreSlave": 21, "GBECoreSlave": 21 + }, + "S5JS100": { + "OGChipSelectEditMenu": "S5JS100\tSamsung S5JS100" } + }