From edf36fb2ae97580ac0b286382bd71818d44939d5 Mon Sep 17 00:00:00 2001 From: Ganesh Ramachandran Date: Mon, 29 Jul 2019 17:41:32 +0530 Subject: [PATCH] Added new features to TMPM46B --- .../Periph_Driver/src/tmpm46b_esg.c | 2 - .../TARGET_TMPM46B/analogin_api.c | 2 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/device.h | 3 +- .../device/TOOLCHAIN_ARM_STD/tmpm46bf10fg.sct | 2 +- .../TARGET_TMPM46B/device/system_TMPM46B.c | 6 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c | 53 +- .../TARGET_TMPM46B/gpio_irq_api.c | 4 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/i2c_api.c | 554 ++++++++++++------ .../TARGET_TOSHIBA/TARGET_TMPM46B/objects.h | 63 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/pinmap.c | 14 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/port_api.c | 8 +- .../TARGET_TMPM46B/pwmout_api.c | 16 +- .../TARGET_TMPM46B/reset_reason_api.c | 4 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/rtc_api.c | 207 +++++++ .../TARGET_TMPM46B/serial_api.c | 40 +- .../TARGET_TOSHIBA/TARGET_TMPM46B/spi_api.c | 294 +++++++++- .../TARGET_TOSHIBA/TARGET_TMPM46B/trng_api.c | 6 +- targets/targets.json | 5 + 18 files changed, 984 insertions(+), 299 deletions(-) create mode 100644 targets/TARGET_TOSHIBA/TARGET_TMPM46B/rtc_api.c diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/Periph_Driver/src/tmpm46b_esg.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/Periph_Driver/src/tmpm46b_esg.c index 466741184e..3898908cca 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/Periph_Driver/src/tmpm46b_esg.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/Periph_Driver/src/tmpm46b_esg.c @@ -244,8 +244,6 @@ FunctionalState ESG_GetIntStatus(void) */ void ESG_IPReset(void) { - uint32_t iprst3 = 0U; - /* Disable write protection state of SRSTIPRST */ TSB_SRST->PROTECT = SRST_PROTECT_DISABLE; diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/analogin_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/analogin_api.c index ae0d132fc7..ac3ff1d634 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/analogin_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/analogin_api.c @@ -76,7 +76,7 @@ uint16_t analogin_read_u16(analogin_t *obj) // Start ADC conversion ADC_Start(TSB_AD); // Wait until AD conversion complete - while(ADC_GetConvertState(TSB_AD).Bit.NormalComplete != 1) { + while (ADC_GetConvertState(TSB_AD).Bit.NormalComplete != 1) { // Do nothing } wait_us(30); diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device.h b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device.h index 73b9c874f9..95257110ac 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device.h +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device.h @@ -16,7 +16,8 @@ #ifndef MBED_DEVICE_H #define MBED_DEVICE_H -#define DEVICE_ID_LENGTH 32 +#define TRANSACTION_QUEUE_SIZE_SPI 4 +#define DEVICE_ID_LENGTH 32 #include "objects.h" #include diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_ARM_STD/tmpm46bf10fg.sct b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_ARM_STD/tmpm46bf10fg.sct index 0c4f778de9..604d3251ec 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_ARM_STD/tmpm46bf10fg.sct +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_ARM_STD/tmpm46bf10fg.sct @@ -45,6 +45,6 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region .ANY (+RW, +ZI) } - ARM_LIB_STACK (0x200001E0+0x80000) EMPTY -Stack_Size { ; stack + ARM_LIB_STACK (0x20000000+0x80000) EMPTY -Stack_Size { ; stack } } diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/system_TMPM46B.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/system_TMPM46B.c index f54fa75426..e068d76286 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/system_TMPM46B.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/system_TMPM46B.c @@ -317,13 +317,11 @@ void SystemInit(void) volatile uint32_t oscf = 0U; uint32_t wdte = 0U; -#if defined ( __CC_ARM )/*Enable FPU for Keil*/ - #if (__FPU_USED == 1) /* __FPU_USED is defined in core_cm4.h */ +#if (__FPU_USED == 1) /* __FPU_USED is defined in core_cm4.h */ /* enable FPU if available and used */ SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ (3UL << 11*2) ); /* set CP11 Full Access */ - #endif -#endif +#endif #if (WD_SETUP) /* Watchdog Setup */ while (TSB_WD->FLG != 0U) { diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c index 0425fd9669..a52dd4ebbd 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c @@ -18,11 +18,11 @@ #include "mbed_critical.h" #include "tmpm46b_fc.h" -#define PROGRAM_WIRTE_MAX 16U /* Page program could be written 16 bytes/4 words once */ -#define SECTOR_SIZE 0x8000 /* (512 * 8) sectors */ -#define PAGE_SIZE 16U /* Page program size is 16 bytes */ +#define PROGRAM_WIRTE_MAX 16U // Page program could be written 16 bytes/4 words once +#define SECTOR_SIZE 0x8000 // (512 * 8) sectors +#define PAGE_SIZE 16U // Page program size is 16 bytes -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #define FLASH_API_ROM ((uint32_t *)__section_begin("FLASH_CODE_ROM")) #define SIZE_FLASH_API ((uint32_t)__section_size("FLASH_CODE_ROM")) #define FLASH_API_RAM ((uint32_t *)__section_begin("FLASH_CODE_RAM")) @@ -30,22 +30,22 @@ #pragma section = "FLASH_CODE_ROM" #endif -#if defined ( __ICCARM__ ) /* IAR Compiler */ -static void Copy_Routine(uint32_t * dest, uint32_t * source, uint32_t size) +#if defined ( __ICCARM__ ) // IAR Compiler +static void Copy_Routine(uint32_t *dest, uint32_t *source, uint32_t size) { uint32_t *dest_addr, *source_addr, tmpsize; uint32_t i, tmps, tmpd, mask; - dest_addr = dest; + dest_addr = dest; source_addr = source; tmpsize = size >> 2U; - for (i = 0U; i < tmpsize; i++) { /* 32bits copy */ + for (i = 0U; i < tmpsize; i++) { // 32bits copy *dest_addr = *source_addr; dest_addr++; source_addr++; } - if (size & 0x00000003U) { /* if the last data size is not 0(maybe 1,2 or 3), copy the last data */ + if (size & 0x00000003U) { // if the last data size is not 0(maybe 1,2 or 3), copy the last data mask = 0xFFFFFF00U; i = size & 0x00000003U; tmps = *source_addr; @@ -56,9 +56,9 @@ static void Copy_Routine(uint32_t * dest, uint32_t * source, uint32_t size) } tmps = tmps & (~mask); tmpd = tmpd & (mask); - *dest_addr = tmps + tmpd; /* 32bits copy, but only change the bytes need to be changed */ + *dest_addr = tmps + tmpd; // 32bits copy, but only change the bytes need to be changed } else { - /* Do nothing */ + // Do nothing } } #endif @@ -69,7 +69,7 @@ int32_t flash_init(flash_t *obj) TSB_FC->PROGCR = 0x00000001U; TSB_FC->ERASECR = 0x00000007U; TSB_FC->AREASEL = 0x00000000U; -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler Copy_Routine(FLASH_API_RAM, FLASH_API_ROM, SIZE_FLASH_API); #endif return 0; @@ -80,36 +80,36 @@ int32_t flash_free(flash_t *obj) return 0; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif int32_t flash_erase_sector(flash_t *obj, uint32_t address) { int status = FAIL; - /* We need to prevent flash accesses during erase operation */ + // We need to prevent flash accesses during erase operation core_util_critical_section_enter(); if (FC_SUCCESS == FC_EraseBlock(address)) { status = SUCCESS; } else { - /* Do nothing */ + // Do nothing } core_util_critical_section_exit(); return status; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) { int status = SUCCESS; - /* We need to prevent flash accesses during program operation */ + // We need to prevent flash accesses during program operation core_util_critical_section_enter(); while (size > PROGRAM_WIRTE_MAX) { - if (FC_SUCCESS == FC_WritePage((uint32_t)address, (uint32_t *)data)) { /* write one page every time */ - /* Do nothing */ + if (FC_SUCCESS == FC_WritePage((uint32_t)address, (uint32_t *)data)) { // write one page every time + // Do nothing } else { status = FAIL; break; @@ -118,8 +118,8 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, address = address + PROGRAM_WIRTE_MAX; data = data + PROGRAM_WIRTE_MAX; } - if (FC_SUCCESS == FC_WritePage((uint32_t)address, (uint32_t *)data)) { /* write the last data, no more than one page */ - /* Do nothing */ + if (FC_SUCCESS == FC_WritePage((uint32_t)address, (uint32_t *)data)) { // write the last data, no more than one page + // Do nothing } else { status = FAIL; } @@ -128,7 +128,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, return status; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) @@ -139,7 +139,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) return SECTOR_SIZE; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif uint32_t flash_get_page_size(const flash_t *obj) @@ -147,7 +147,7 @@ uint32_t flash_get_page_size(const flash_t *obj) return PAGE_SIZE; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif uint32_t flash_get_start_address(const flash_t *obj) @@ -155,7 +155,7 @@ uint32_t flash_get_start_address(const flash_t *obj) return FLASH_START_ADDR; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif uint32_t flash_get_size(const flash_t *obj) @@ -163,7 +163,7 @@ uint32_t flash_get_size(const flash_t *obj) return FLASH_CHIP_SIZE; } -#if defined ( __ICCARM__ ) /* IAR Compiler */ +#if defined ( __ICCARM__ ) // IAR Compiler #pragma location = "FLASH_ROM" #endif uint8_t flash_get_erase_value(const flash_t *obj) @@ -172,4 +172,3 @@ uint8_t flash_get_erase_value(const flash_t *obj) return 0xFF; } - diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/gpio_irq_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/gpio_irq_api.c index 512d6851a6..4ff11d9878 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/gpio_irq_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/gpio_irq_api.c @@ -37,9 +37,9 @@ static gpio_irq_handler hal_irq_handler[CHANNEL_NUM] = {NULL}; static void INT_IRQHandler(PinName pin, GPIO_IRQName irq_id, uint32_t index) { - uint32_t val; + uint32_t val; GPIO_Port port; - uint32_t mask; + uint32_t mask; port = (GPIO_Port)(pin >> 3); mask = 0x01 << (pin & 0x07); diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/i2c_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/i2c_api.c index 897f92e118..d74d8f1a68 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/i2c_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/i2c_api.c @@ -21,9 +21,35 @@ #include "PeripheralNames.h" #include "pinmap.h" #include "tmpm46b_i2c.h" +#include "mbed_wait_api.h" #include #include +#define SBI_I2C_SEND 0x00 +#define SBI_I2C_RECEIVE 0x01 +#define I2C_TRANSFER_STATE_IDLE (0x0U) +#define I2C_TRANSFER_STATE_BUSY (0x1U) +#define I2C_ACK (1) +#define I2C_NO_DATA (0) +#define I2C_READ_ADDRESSED (1) +#define I2C_WRITE_ADDRESSED (3) +#define I2C_TIMEOUT (100000) +#define I2CCR2_REPEATED_START_CONDITION ((uint32_t)0x00000018) + +#if DEVICE_I2C_ASYNCH +#define I2C_S(obj) (struct i2c_s *) (&(obj->i2c)) +#else +#define I2C_S(obj) (struct i2c_s *) (obj) +#endif + +static inline void repeated_start(struct i2c_s *obj_s); +static int32_t wait_status(i2c_t *obj); +static void I2C_Start_Condition(struct i2c_s *p_obj, uint32_t data); + +#if DEVICE_I2C_ASYNCH +static inline void state_idle(struct i2c_s *obj_s); +#endif + static const PinMap PinMap_I2C_SDA[] = { {PK2, I2C_0, PIN_DATA(3, 2)}, {PF7, I2C_1, PIN_DATA(4, 2)}, @@ -38,80 +64,61 @@ static const PinMap PinMap_I2C_SCL[] = { {NC, NC, 0} }; -#define SBI_I2C_SEND 0x00 -#define SBI_I2C_RECEIVE 0x01 -#define MAX_NUM_I2C 3 -#define DELAY_MS_MULTIPLIER 5500 - -struct i2c_xfer { - int32_t count; - int32_t len; - void *done; - char *buf; -}; - // Clock setting structure definition typedef struct { uint32_t sck; uint32_t prsck; } I2C_clock_setting_t; -static void DelayMS(uint32_t delay) -{ - volatile uint32_t VarI; - for (VarI = 0; VarI < delay * DELAY_MS_MULTIPLIER; VarI++); -} - static const uint32_t I2C_SCK_DIVIDER_TBL[8] = { 20, 24, 32, 48, 80, 144, 272, 528 }; // SCK Divider value table +static int32_t start_flag = 0; +static I2C_State status; static I2C_clock_setting_t clk; static I2C_InitTypeDef myi2c; -static int32_t start_flag = 1; -static struct i2c_xfer xfer[MAX_NUM_I2C]; -static TSB_I2C_TypeDef *i2c_lut[MAX_NUM_I2C] = {TSB_I2C0, TSB_I2C1, TSB_I2C2}; -static char *gI2C_TxData = NULL; -static char *gI2C_LTxData = NULL; -static uint8_t send_byte = 0; -static uint8_t byte_func = 0; // Initialize the I2C peripheral. It sets the default parameters for I2C void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + struct i2c_s *obj_s = I2C_S(obj); MBED_ASSERT(obj != NULL); I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); I2CName i2c_name = (I2CName)pinmap_merge(i2c_sda, i2c_scl); MBED_ASSERT((int)i2c_name != NC); - switch(i2c_name) { + switch (i2c_name) { case I2C_0: CG_SetFcPeriphB(CG_FC_PERIPH_I2C0, ENABLE); CG_SetFcPeriphA(CG_FC_PERIPH_PORTK, ENABLE); - obj->i2c = TSB_I2C0; - obj->index = 0; - obj->IRQn = INTI2C0_IRQn; + obj_s->i2c = TSB_I2C0; + obj_s->index = 0; + obj_s->IRQn = INTI2C0_IRQn; break; case I2C_1: CG_SetFcPeriphB(CG_FC_PERIPH_I2C1, ENABLE); CG_SetFcPeriphA(CG_FC_PERIPH_PORTF, ENABLE); - obj->i2c = TSB_I2C1; - obj->index = 1; - obj->IRQn = INTI2C1_IRQn; + obj_s->i2c = TSB_I2C1; + obj_s->index = 1; + obj_s->IRQn = INTI2C1_IRQn; break; case I2C_2: CG_SetFcPeriphB(CG_FC_PERIPH_I2C2, ENABLE); CG_SetFcPeriphA(CG_FC_PERIPH_PORTH, ENABLE); - obj->i2c = TSB_I2C2; - obj->index = 2; - obj->IRQn = INTI2C2_IRQn; + obj_s->i2c = TSB_I2C2; + obj_s->index = 2; + obj_s->IRQn = INTI2C2_IRQn; break; default: error("I2C is not available"); break; } +#if DEVICE_I2C_ASYNCH + obj_s->state = I2C_TRANSFER_STATE_IDLE; +#endif pinmap_pinout(sda, PinMap_I2C_SDA); pin_mode(sda, OpenDrain); pin_mode(sda, PullUp); @@ -120,6 +127,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) pin_mode(scl, OpenDrain); pin_mode(scl, PullUp); + NVIC_DisableIRQ(obj_s->IRQn); i2c_reset(obj); i2c_frequency(obj, 100000); } @@ -127,13 +135,14 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) // Configure the I2C frequency void i2c_frequency(i2c_t *obj, int hz) { - uint32_t sck = 0; - uint32_t tmp_sck = 0; - uint32_t prsck = 1; - uint32_t tmp_prsck = 1; - uint32_t fscl = 0; - uint32_t tmp_fscl = 0; - uint64_t fx; + struct i2c_s *obj_s = I2C_S(obj); + uint32_t sck = 0; + uint32_t tmp_sck = 0; + uint32_t prsck = 1; + uint32_t tmp_prsck = 1; + uint32_t fscl = 0; + uint32_t tmp_fscl = 0; + uint64_t fx = 0; if (hz <= 400000) { // Maximum 400khz clock frequency supported by M46B for (prsck = 1; prsck <= 32; prsck++) { @@ -161,10 +170,9 @@ void i2c_frequency(i2c_t *obj, int hz) myi2c.I2CClkDiv = clk.sck; myi2c.PrescalerClkDiv = clk.prsck; - I2C_SWReset(obj->i2c); - I2C_Init(obj->i2c, &myi2c); - NVIC_EnableIRQ(obj->IRQn); - I2C_SetINTReq(obj->i2c, ENABLE); + I2C_SWReset(obj_s->i2c); + I2C_Init(obj_s->i2c, &myi2c); + NVIC_DisableIRQ(obj_s->IRQn); } int i2c_start(i2c_t *obj) @@ -175,187 +183,389 @@ int i2c_start(i2c_t *obj) int i2c_stop(i2c_t *obj) { - I2C_GenerateStop(obj->i2c); + struct i2c_s *obj_s = I2C_S(obj); + I2C_GenerateStop(obj_s->i2c); return 0; } void i2c_reset(i2c_t *obj) { - I2C_SWReset(obj->i2c); -} - -static void wait_i2c_bus_free(i2c_t *obj) -{ - I2C_State status; - - do { - status = I2C_GetState(obj->i2c); - } while (status.Bit.BusState); + struct i2c_s *obj_s = I2C_S(obj); + I2C_SWReset(obj_s->i2c); } int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { - TSB_I2C_TypeDef *sbi = obj->i2c; - uint32_t i2c_num = 0; - obj->address = address; + int32_t result = 0; + int32_t count = 0; - i2c_num = obj->index; + if (length > 0) { + start_flag = 1; // Start Condition + if (i2c_byte_write(obj, (int32_t)((uint32_t)address | 1U)) == I2C_ACK) { + while (count < length) { + int32_t pdata = i2c_byte_read(obj, ((count < (length - 1)) ? 0 : 1)); + if (pdata < 0) { + break; + } + data[count++] = (uint8_t)pdata; + } + result = count; + } else { + stop = 1; + result = I2C_ERROR_NO_SLAVE; + } - // receive data - xfer[i2c_num].count = 0; - xfer[i2c_num].len = length; - xfer[i2c_num].buf = data; - - I2C_SetSendData(sbi, address | SBI_I2C_RECEIVE); - I2C_GenerateStart(sbi); - - wait_i2c_bus_free(obj); - return (xfer[i2c_num].count - 1); + if (stop) { // Stop Condition + i2c_stop(obj); + } + } + return (result); } int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { - int8_t i = 0; - TSB_I2C_TypeDef *sbi = obj->i2c; - uint32_t i2c_num = 0; - obj->address = address; + int32_t result = 0; + int32_t count = 0; - i2c_num = obj->index; - gI2C_TxData = (char *)calloc(length, sizeof(int8_t)); - if (gI2C_TxData == NULL) { - error("Insufficient memory"); - return 0; + start_flag = 1; // Start Condition + if (i2c_byte_write(obj, address) == I2C_ACK) { + while (count < length) { + if (i2c_byte_write(obj, (int32_t)data[count++]) < I2C_ACK) { + break; + } + } + result = count; + } else { + stop = 1; + result = I2C_ERROR_NO_SLAVE; } - for (i = 0; i < length; i++) { - gI2C_TxData[i] = data[i]; + if (stop) { // Stop Condition + i2c_stop(obj); } - // receive data - xfer[i2c_num].count = 0; - xfer[i2c_num].len = length; - xfer[i2c_num].buf = gI2C_TxData; - - I2C_SetSendData(sbi, address | SBI_I2C_SEND); - I2C_GenerateStart(sbi); // Start condition - - wait_i2c_bus_free(obj); - free(gI2C_TxData); - DelayMS(8); - if (((xfer[i2c_num].count - 1) == 0) && (byte_func == 1)) { - send_byte = 1; - i2c_byte_write(obj, 0x00); - xfer[i2c_num].count = 1; - byte_func = 0; - } - return (xfer[i2c_num].count - 1); + return (result); } int i2c_byte_read(i2c_t *obj, int last) { - char i2c_ret = 0; - i2c_read(obj, obj->address, &i2c_ret, 1, last); - return i2c_ret; + struct i2c_s *obj_s = I2C_S(obj); + + int32_t result; + + I2C_ClearINTOutput(obj_s->i2c); + + if (last) { + I2C_SetACK(obj_s->i2c, DISABLE); + } else { + I2C_SetACK(obj_s->i2c, ENABLE); + } + I2C_SetSendData(obj_s->i2c, 0x00); + + if (wait_status(obj) < 0) { + result = -1; + } else { + result = (int32_t)I2C_GetReceiveData(obj_s->i2c); + } + return (result); } int i2c_byte_write(i2c_t *obj, int data) { - uint32_t wb = 1; - static size_t counter = 1; + struct i2c_s *obj_s = I2C_S(obj); - byte_func = 1; - if (start_flag == 0 && send_byte == 0) { - gI2C_LTxData = (char *)realloc(gI2C_LTxData, counter++); - if (gI2C_LTxData == NULL) { - error("Insufficient memory"); - return 0; - } - gI2C_LTxData[counter - 2] = data; - } + int32_t result; - if (send_byte == 1) { - wb = i2c_write(obj, obj->address, gI2C_LTxData, (counter - 1), 0); - start_flag = 1; - send_byte = 0; - byte_func = 0; - counter = 1; - return wb; + I2C_ClearINTOutput(obj_s->i2c); + + if (start_flag == 1) { + I2C_Start_Condition(obj_s, (uint32_t)data); + start_flag = 0; } else { - if (start_flag == 1) { - obj->address = data; - start_flag = 0; - } else { - // Store the number of written bytes - wb = i2c_write(obj, obj->address, (char*)&data, 1, 0); - } - if (wb == 1) - return 1; - else - return 0; + I2C_SetSendData(obj_s->i2c, (uint32_t)data); } + + if (wait_status(obj) < 0) { + return (-1); + } + + status = I2C_GetState(obj_s->i2c); + if (!status.Bit.LastRxBit) { + result = 1; + } else { + result = 0; + } + return (result); } -static void i2c_irq_handler(int i2c_num) +void i2c_slave_mode(i2c_t *obj, int enable_slave) { - uint32_t tmp = 0U; - TSB_I2C_TypeDef *sbi = i2c_lut[i2c_num]; - I2C_State sbi_sr; + i2c_reset(obj); + struct i2c_s *obj_s = I2C_S(obj); - sbi_sr = I2C_GetState(sbi); + obj_s->myi2c.I2CDataLen = I2C_DATA_LEN_8; + obj_s->myi2c.I2CACKState = ENABLE; + obj_s->myi2c.I2CClkDiv = clk.sck; + obj_s->myi2c.PrescalerClkDiv = clk.prsck; - // we don't support slave mode - if (!sbi_sr.Bit.MasterSlave) - return; + if (enable_slave) { + obj_s->myi2c.I2CSelfAddr = obj_s->address; + I2C_SetINTReq(obj_s->i2c, ENABLE); + } else { + obj_s->myi2c.I2CSelfAddr = 0xE0; + NVIC_DisableIRQ(obj_s->IRQn); + I2C_ClearINTOutput(obj_s->i2c); + } + I2C_Init(obj_s->i2c, &obj_s->myi2c); +} - if (sbi_sr.Bit.TRx) { // Tx mode - if (sbi_sr.Bit.LastRxBit) { // LRB=1: the receiver requires no further data. - I2C_GenerateStop(sbi); - } else { // LRB=0: the receiver requires further data. - if (xfer[i2c_num].count < xfer[i2c_num].len) { - I2C_SetSendData(sbi, xfer[i2c_num].buf[xfer[i2c_num].count]); // Send next data - } else if (xfer[i2c_num].count == xfer[i2c_num].len) { // I2C data send finished. - I2C_GenerateStop(sbi); - } else { - // Do nothing - } - xfer[i2c_num].count++; - } - } else { // Rx Mode - if (xfer[i2c_num].count > xfer[i2c_num].len) { - I2C_GenerateStop(sbi); - I2C_SetACK(sbi, ENABLE); +int i2c_slave_receive(i2c_t *obj) +{ + struct i2c_s *obj_s = I2C_S(obj); + int32_t result = I2C_NO_DATA; + + if ((I2C_GetINTStatus(obj_s->i2c)) && (I2C_GetSlaveAddrMatchState(obj_s->i2c))) { + status = I2C_GetState(obj_s->i2c); + if (!status.Bit.TRx) { + result = I2C_WRITE_ADDRESSED; } else { - if (xfer[i2c_num].count == xfer[i2c_num].len) { // Rx last data - I2C_SetBitNum(sbi, I2C_DATA_LEN_1); - } else if (xfer[i2c_num].count == (xfer[i2c_num].len - 1)) { // Rx the data second to last - // Not generate ACK for next data Rx end. - I2C_SetACK(sbi, DISABLE); + result = I2C_READ_ADDRESSED; + } + } + return (result); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) +{ + struct i2c_s *obj_s = I2C_S(obj); + int32_t count = 0; + + while (count < length) { + int32_t pdata = i2c_byte_read(obj, 0); + status = I2C_GetState(obj_s->i2c); + if (status.Bit.TRx) { + return (count); + } else { + if (pdata < 0) { + break; + } + data[count++] = (uint8_t)pdata; + } + } + i2c_slave_mode(obj, 1); + return (count); +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) +{ + int32_t count = 0; + + while (count < length) { + if (i2c_byte_write(obj, (int32_t)data[count++]) < I2C_ACK) { + break; + } + } + i2c_slave_mode(obj, 1); + return (count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) +{ + struct i2c_s *obj_s = I2C_S(obj); + obj_s->address = address & 0xFE; + i2c_slave_mode(obj, 1); +} + + +#if DEVICE_I2C_ASYNCH +void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, + uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) +{ + struct i2c_s *obj_s = I2C_S(obj); + obj_s->event_mask = event; + obj_s->stop = stop; + obj_s->address = address; + + // copy the buffers to the I2C object + obj->tx_buff.buffer = (void *) tx; + obj->tx_buff.length = tx ? tx_length : 0; + obj->tx_buff.pos = 0; + + obj->rx_buff.buffer = rx; + obj->rx_buff.length = rx ? rx_length : 0; + obj->rx_buff.pos = 0; + + obj_s->state = I2C_TRANSFER_STATE_BUSY; + I2C_SetINTReq(obj_s->i2c, ENABLE); + NVIC_ClearPendingIRQ(obj_s->IRQn); + NVIC_SetVector(obj_s->IRQn, (uint32_t)handler); + NVIC_EnableIRQ(obj_s->IRQn); + + if ((tx_length == 0) && (rx_length != 0)) { + I2C_SetSendData(obj_s->i2c, address | SBI_I2C_RECEIVE); + } else { + I2C_SetSendData(obj_s->i2c, address | SBI_I2C_SEND); + } + I2C_GenerateStart(obj_s->i2c); +} + +uint32_t i2c_irq_handler_asynch(i2c_t *obj) +{ + struct i2c_s *obj_s = I2C_S(obj); + uint32_t tmp_read = 0U; + uint32_t event = 0; + I2C_State flag_state; + + flag_state = I2C_GetState(obj_s->i2c); + + if ((!flag_state.Bit.MasterSlave) || (obj_s->state != I2C_TRANSFER_STATE_BUSY)) { + I2C_GenerateStop(obj_s->i2c); + event = I2C_EVENT_ERROR; + state_idle(obj_s); + return (event & obj_s->event_mask); + } + + if (flag_state.Bit.TRx) { // Transmit + + if (flag_state.Bit.LastRxBit) { // NACK Recieved + I2C_GenerateStop(obj_s->i2c); + + if (obj->tx_buff.pos == 0) { + I2C_GenerateStop(obj_s->i2c); + event = (I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE); + state_idle(obj_s); + + } else { + I2C_GenerateStop(obj_s->i2c); + event = (I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK); + state_idle(obj_s); + } + + } else { // ACK Received + + if (obj->tx_buff.pos < obj->tx_buff.length) { + I2C_SetSendData(obj_s->i2c, (*((uint8_t *)obj->tx_buff.buffer + obj->tx_buff.pos) & 0xFF)); // Send next data + obj->tx_buff.pos++; + + } else if (obj->rx_buff.length != 0) { // Transmit complete Receive Pending + repeated_start(obj_s); + I2C_SetSendData(obj_s->i2c, obj_s->address | SBI_I2C_RECEIVE); + + } else { // Transmit complete and NO data to Receive + I2C_GenerateStop(obj_s->i2c); + event = I2C_EVENT_TRANSFER_COMPLETE; + state_idle(obj_s); + } + } + } else { // Receive + + if (obj->rx_buff.pos > obj->rx_buff.length) { + I2C_GenerateStop(obj_s->i2c); + event = I2C_EVENT_TRANSFER_COMPLETE; + state_idle(obj_s); + I2C_SetACK(obj_s->i2c, ENABLE); + + } else { + + if (obj->rx_buff.pos == obj->rx_buff.length) { + I2C_SetBitNum(obj_s->i2c, I2C_DATA_LEN_1); + + } else if (obj->rx_buff.pos == (obj->rx_buff.length - 1)) { + I2C_SetACK(obj_s->i2c, DISABLE); + } else { // Do nothing } - tmp = I2C_GetReceiveData(sbi); - if (xfer[i2c_num].count > 0) { - xfer[i2c_num].buf[xfer[i2c_num].count - 1U] = tmp; + + tmp_read = I2C_GetReceiveData(obj_s->i2c); + + if (obj->rx_buff.pos > 0) { + *((uint8_t *)obj->rx_buff.buffer + (obj->rx_buff.pos - 1)) = tmp_read; } else { // first read is dummy read } - xfer[i2c_num].count++; + obj->rx_buff.pos++; } } + + return (event & obj_s->event_mask); } -void INTI2C0_IRQHandler(void) +uint8_t i2c_active(i2c_t *obj) { - i2c_irq_handler(0); + struct i2c_s *obj_s = I2C_S(obj); + + return (obj_s->state != I2C_TRANSFER_STATE_IDLE); } -void INTI2C1_IRQHandler(void) +void i2c_abort_asynch(i2c_t *obj) { - i2c_irq_handler(1); + struct i2c_s *obj_s = I2C_S(obj); + + I2C_ClearINTReq(obj_s->i2c); + NVIC_ClearPendingIRQ(obj_s->IRQn); + I2C_GenerateStop(obj_s->i2c); + state_idle(obj_s); + I2C_SWReset(obj_s->i2c); + I2C_Init(obj_s->i2c, &obj_s->myi2c); } -void INTI2C2_IRQHandler(void) +static inline void state_idle(struct i2c_s *obj_s) { - i2c_irq_handler(2); + I2C_State flag_state; + + obj_s->state = I2C_TRANSFER_STATE_IDLE; + NVIC_DisableIRQ(obj_s->IRQn); + I2C_SetINTReq(obj_s->i2c, DISABLE); + // wait until bus state releases after stop condition + do { + flag_state = I2C_GetState(obj_s->i2c); + } while (flag_state.Bit.BusState); + // To satisfy the setup time of restart, at least 4.7µs wait must be created by software (Ref. TRM pg. 561) + wait_us(5); +} + +#endif //DEVICE_I2C_ASYNCH + +static int32_t wait_status(i2c_t *obj) +{ + struct i2c_s *obj_s = I2C_S(obj); + volatile int32_t timeout = I2C_TIMEOUT; + + while (I2C_GetINTStatus(obj_s->i2c) == DISABLE) { + if ((timeout--) == 0) { + return (-1); + } + } + return (0); +} + +static inline void repeated_start(struct i2c_s *obj_s) +{ + I2C_State flag_state; + + obj_s->i2c->CR2 = I2CCR2_REPEATED_START_CONDITION; + // wait until bus state releases + do { + flag_state = I2C_GetState(obj_s->i2c); + } while (flag_state.Bit.BusState); + // Checks that no other device is pulling the SCL pin to "Low". + do { + flag_state = I2C_GetState(obj_s->i2c); + } while (!flag_state.Bit.LastRxBit); + + I2C_GenerateStart(obj_s->i2c); +} + +static void I2C_Start_Condition(struct i2c_s *p_obj, uint32_t data) +{ + status = I2C_GetState(p_obj->i2c); + if (status.Bit.BusState) { + repeated_start(p_obj); + I2C_SetSendData(p_obj->i2c, (uint32_t)data); + } else { + I2C_SetSendData(p_obj->i2c, (uint32_t)data); + I2C_GenerateStart(p_obj->i2c); + } } const PinMap *i2c_master_sda_pinmap() diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/objects.h b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/objects.h index b6bc292ca5..a0582a3a6d 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/objects.h +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/objects.h @@ -31,11 +31,11 @@ extern "C" { #endif struct gpio_irq_s { - uint32_t mask; - GPIO_Port port; - uint32_t irq_id; - CG_INTActiveState event; - CG_INTSrc irq_src; + uint32_t mask; + GPIO_Port port; + uint32_t irq_id; + CG_INTActiveState event; + CG_INTSrc irq_src; }; struct port_s { @@ -44,43 +44,54 @@ struct port_s { }; struct pwmout_s { - PinName pin; - TSB_TB_TypeDef * channel; - uint16_t trailing_timing; - uint16_t leading_timing; - uint16_t divisor; - float period; + PinName pin; + TSB_TB_TypeDef *channel; + uint16_t trailing_timing; + uint16_t leading_timing; + uint16_t divisor; + float period; }; struct serial_s { - PinName pin; - uint32_t index; - TSB_SC_TypeDef * UARTx; - TSB_FUART_TypeDef *FUART; - UART_InitTypeDef uart_config; - FUART_InitTypeDef fuart_config; - TSB_UART_TypeDef *FUART_Reg; + PinName pin; + uint32_t index; + TSB_SC_TypeDef *UARTx; + TSB_FUART_TypeDef *FUART; + UART_InitTypeDef uart_config; + FUART_InitTypeDef fuart_config; + TSB_UART_TypeDef *FUART_Reg; }; struct analogin_s { - PinName pin; - ADCName adc; - TSB_AD_TypeDef* obj; - ADC_AINx channel; + PinName pin; + ADCName adc; + TSB_AD_TypeDef *obj; + ADC_AINx channel; }; struct i2c_s { - uint32_t index; - int address; + uint32_t index; + int address; IRQn_Type IRQn; TSB_I2C_TypeDef *i2c; I2C_InitTypeDef myi2c; +#ifdef DEVICE_I2C_ASYNCH + uint32_t event_mask; + uint8_t stop; + uint8_t state; +#endif }; struct spi_s { TSB_SSP_TypeDef *spi; - SPIName module; - uint8_t bits; + SPIName module; + uint8_t bits; + PinName clk_pin; + IRQn_Type irqn; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event_mask; + uint8_t state; +#endif }; struct trng_s { diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pinmap.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pinmap.c index 10e5836a64..fb6bfc7c1a 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pinmap.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pinmap.c @@ -21,11 +21,11 @@ void pin_function(PinName pin, int function) { - uint32_t port = 0; - uint8_t bit = 0; - uint8_t i = 0; - uint8_t func = 0; - uint8_t dir = 0; + uint32_t port = 0; + uint8_t bit = 0; + uint8_t i = 0; + uint8_t func = 0; + uint8_t dir = 0; // Assert that pin is valid MBED_ASSERT(pin != NC); @@ -71,8 +71,8 @@ void pin_function(PinName pin, int function) void pin_mode(PinName pin, PinMode mode) { - uint32_t port = 0; - uint8_t bit = 0; + uint32_t port = 0; + uint8_t bit = 0; // Assert that pin is valid MBED_ASSERT(pin != NC); diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/port_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/port_api.c index f68aaf9b74..86551ca981 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/port_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/port_api.c @@ -89,8 +89,8 @@ void port_dir(port_t *obj, PinDirection dir) void port_write(port_t *obj, int value) { - uint8_t port_data = 0; - uint8_t data = 0; + uint8_t port_data = 0; + uint8_t data = 0; // Assert that port is valid MBED_ASSERT(obj->port <= PortL); @@ -105,8 +105,8 @@ void port_write(port_t *obj, int value) int port_read(port_t *obj) { - uint8_t port_data = 0; - uint8_t data = 0; + uint8_t port_data = 0; + uint8_t data = 0; // Assert that port is valid MBED_ASSERT(obj->port <= PortL); diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c index 62db77f0ab..d68254a7ca 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c @@ -138,12 +138,12 @@ void pwmout_period_ms(pwmout_t *obj, int ms) // Set the PWM period, keeping the duty cycle the same. void pwmout_period_us(pwmout_t *obj, int us) { - float seconds = 0; - uint32_t cycles = 0; - int ClkDiv = 0; - int i = 0; - float duty_cycle = 0; - uint32_t clk_freq = 0; + float seconds = 0; + uint32_t cycles = 0; + int ClkDiv = 0; + int i = 0; + float duty_cycle = 0; + uint32_t clk_freq = 0; seconds = (float)((us) / 1000000.0f); obj->period = seconds; @@ -204,8 +204,8 @@ void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) void pwmout_pulsewidth_us(pwmout_t *obj, int us) { - float seconds = 0; - float value = 0; + float seconds = 0; + float value = 0; seconds = (float)(us / 1000000.0f); value = (((seconds / obj->period) * 100.0f) / 100.0f); diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/reset_reason_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/reset_reason_api.c index 1d6546fceb..34176775d9 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/reset_reason_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/reset_reason_api.c @@ -69,7 +69,7 @@ reset_reason_t hal_reset_reason_get(void) static uint8_t set_bit_count(uint32_t reg) { uint8_t count = 0; - int8_t index = 0; + uint8_t index = 0; for (index = 0; index < (sizeof(uint32_t) * 8); index++) { if ((reg & (1 << index)) && index != 1) { @@ -89,6 +89,8 @@ static uint8_t bit_pos(uint32_t reg) return bit_no; } } + + return 0; } #endif // DEVICE_RESET_REASON diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/rtc_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/rtc_api.c new file mode 100644 index 0000000000..22181ba586 --- /dev/null +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/rtc_api.c @@ -0,0 +1,207 @@ +/* mbed Microcontroller Library + * (C)Copyright TOSHIBA ELECTRONIC DEVICES & STORAGE CORPORATION 2017 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 "rtc_api.h" +#include "mbed_mktime.h" + +#define CG_OSCCR_XTEN_SET ((uint32_t)0x00000008) +#define CG_OSCCR_DRVOSCL_SET ((uint32_t)0x00000080) + +#define RTC_24_HOUR_MODE ((uint8_t)0x01) +#define PAGER_PAGE_ONE ((uint8_t)0x01) +#define PAGER_PAGE_ZERO ((uint8_t)0xEE) +#define RTC_CLK_ENABLE ((uint8_t)0x08) +#define RTC_CLK_DISABLE ((uint8_t)0xE7) +#define RTCRESTR_RSTTMR_MASK ((uint8_t)0x20) +#define RTCRESTR_RSTTMR_R_RUN ((uint8_t)0x20) +#define CGWUPLCR_WUPTL_HIGH_MASK ((uint32_t)0x07FFF000) +#define CGWUPLCR_WULEF_MASK ((uint32_t)0x00000002) +#define CGWUPLCR_WULEF_R_DONE ((uint32_t)0x00000000) +#define CGWUPLCR_WULON_W_ENABLE ((uint32_t)0x00000001) +#define RLMLOSCCR_XTEN_RW_ENABLE ((uint32_t)0x00000003) +#define ELOSC_CFG_WARM_UP_TIME ((uint64_t)(5000)) +#define ELOSC_CFG_CLOCK ((uint64_t)(32768)) +#define HEX2DEC(val) ((val >> 4U) * 10U + val % 16U) // Hex to Dec conversion macro +#define DEC2HEX(val) ((val / 10U) * 16U + val % 10U) // Dec to Hex conversion macro + +static int rtc_inited = 0; +static int diff_year = 100; //our RTC register only support 2000~2099 + +void rtc_init(void) +{ + if (!rtc_inited) { + // Enable low-speed oscillator + TSB_CG->OSCCR |= CG_OSCCR_XTEN_SET; + TSB_CG->OSCCR |= CG_OSCCR_DRVOSCL_SET; + + TSB_RTC->PAGER = 0x00; // Disable clock and alarm + + while ((TSB_RTC->RESTR & RTCRESTR_RSTTMR_MASK) == RTCRESTR_RSTTMR_R_RUN) { + // Reset RTC sec counter + } + + TSB_RTC->RESTR = 0xE7; + + while ((TSB_RTC->RESTR & RTCRESTR_RSTTMR_MASK) == RTCRESTR_RSTTMR_R_RUN) { + // Reset RTC sec counter + } + + TSB_RTC->PAGER |= PAGER_PAGE_ONE; + TSB_RTC->YEARR = 0x03; // Set leap year state + TSB_RTC->MONTHR = RTC_24_HOUR_MODE; // Set hour mode + TSB_RTC->PAGER &= PAGER_PAGE_ZERO; // Set hour mode + TSB_RTC->YEARR = 0x01; // Set year value + TSB_RTC->MONTHR = (uint8_t)0x01; // Set month value + TSB_RTC->DATER = (uint8_t)0x01; // Set date value + TSB_RTC->DAYR = (uint8_t)0x0; // Set day value + TSB_RTC->HOURR = (uint8_t)0x01; // Set hour value + TSB_RTC->MINR = (uint8_t)0x02; // Set minute value + TSB_RTC->SECR = (uint8_t)0x22; // Set second value + TSB_RTC->PAGER |= RTC_CLK_ENABLE; // Enable Clock + rtc_inited = 1; // Enable RTC initialzed status + } +} + +void rtc_free(void) +{ + rtc_inited = 0; // Set status of RTC peripheral driver as DISABLE +} + +int rtc_isenabled(void) +{ + return rtc_inited; // Return status of RTC peripheral driver +} + +time_t rtc_read(void) +{ + if (!rtc_inited) { + // Return invalid time for now! + return 0; + } + + struct tm timeinfo; + uint8_t read_1 = 0U; + uint8_t read_2 = 0U; + + timeinfo.tm_isdst = 0;//no summer time + + TSB_RTC->PAGER &= PAGER_PAGE_ZERO; + + read_1 = TSB_RTC->SECR; // Get sec value + timeinfo.tm_sec = HEX2DEC(read_1); + + do { // Get minute value + read_1 = TSB_RTC->MINR; + read_2 = TSB_RTC->MINR; + } while (read_1 != read_2); + timeinfo.tm_min = HEX2DEC(read_1); + + do { // Get hour value + read_1 = TSB_RTC->HOURR; + read_2 = TSB_RTC->HOURR; + } while (read_1 != read_2); + timeinfo.tm_hour = HEX2DEC(read_1); + + do { // Get Month date value + read_1 = TSB_RTC->DATER; + read_2 = TSB_RTC->DATER; + } while (read_1 != read_2); + timeinfo.tm_mday = HEX2DEC(read_1); + + do { // Get Month value + read_1 = TSB_RTC->MONTHR; + read_2 = TSB_RTC->MONTHR; + } while (read_1 != read_2); + timeinfo.tm_mon = HEX2DEC(read_1)-1; + + do { // Get weekday value + read_1 = TSB_RTC->DAYR; + read_2 = TSB_RTC->DAYR; + } while (read_1 != read_2); + timeinfo.tm_wday = HEX2DEC(read_1); + + do { // Get year value + read_1 = TSB_RTC->YEARR; + read_2 = TSB_RTC->YEARR; + } while (read_1 != read_2); + timeinfo.tm_year = (HEX2DEC(read_1)+ diff_year); + + time_t t; + + if (_rtc_maketime(&timeinfo, &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) { + return 0; + } + return t; +} + +void rtc_write(time_t t) +{ + if (!rtc_inited) { + // Initialize the RTC as not yet initialized + rtc_init(); + } + + struct tm timeinfo; + if (_rtc_localtime(t, &timeinfo, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) { + return; + } + + diff_year = timeinfo.tm_year - (timeinfo.tm_year % 100); + + TSB_RTC->PAGER &= RTC_CLK_DISABLE; // Disable clock + + // Check current year is leap year or not + if (((timeinfo.tm_year % 4) == 0 && (timeinfo.tm_year % 100) != 0) || + (timeinfo.tm_year % 400) == 0) { + TSB_RTC->PAGER |= PAGER_PAGE_ONE; // Current year is a leap year + TSB_RTC->YEARR = 0x00; + } else if ((timeinfo.tm_year % 4) == 1) { + TSB_RTC->PAGER |= PAGER_PAGE_ONE; // Current year is the year following a leap year + TSB_RTC->YEARR = 0x01; + } else if ((timeinfo.tm_year % 4) == 2) { + TSB_RTC->PAGER |= PAGER_PAGE_ONE; // Current year is two years after a leap year + TSB_RTC->YEARR = 0x02; + } else { + TSB_RTC->PAGER |= PAGER_PAGE_ONE; // Current year is three years after a leap year + TSB_RTC->YEARR = 0x03; + } + + TSB_RTC->PAGER &= PAGER_PAGE_ZERO; // Select PAGE 0 + TSB_RTC->YEARR = (uint8_t)DEC2HEX((timeinfo.tm_year - diff_year)); // Set year value + // Set month value, tm_mon=0 means Jan while 1 is Jan in M3H + TSB_RTC->MONTHR = (uint8_t)DEC2HEX((timeinfo.tm_mon+1)); + TSB_RTC->DATER = (uint8_t)DEC2HEX(timeinfo.tm_mday); // Set date value + TSB_RTC->DAYR = (uint8_t)(timeinfo.tm_wday); // Set week day value + TSB_RTC->HOURR = (uint8_t)DEC2HEX(timeinfo.tm_hour); // Set hour value + TSB_RTC->MINR = (uint8_t)DEC2HEX(timeinfo.tm_min); // Set minute value + TSB_RTC->SECR = (uint8_t)DEC2HEX(timeinfo.tm_sec); // Set second value + + // Setting Wait + // When stop mode is selected, CaseA or CaseB is need. + // CaseA: Wait for RTC 1Hz interrupt. + // CaseB: Check the clock register setting. + { + uint8_t flag = 1; + time_t time_read = {0}; + while (flag) { + time_read = rtc_read(); + if (time_read == t) { // Wait for setting successfully + flag = 0; + } + } + } + TSB_RTC->PAGER |= RTC_CLK_ENABLE; // Enable Clock +} diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/serial_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/serial_api.c index 4faa91cc21..090b1599fb 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/serial_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/serial_api.c @@ -193,6 +193,8 @@ void serial_free(serial_t *obj) obj->fuart_config.Mode = 0; obj->fuart_config.FlowCtrl = 0; break; + default: + break; } } @@ -214,6 +216,8 @@ void serial_baud(serial_t *obj, int baudrate) FUART_Init(obj->FUART,&obj->fuart_config); FUART_Enable(obj->FUART); break; + default: + break; } } @@ -231,10 +235,10 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b case SERIAL_3: MBED_ASSERT((data_bits > 6) && (data_bits < 10)); // 0: 7 data bits ... 2: 9 data bits obj->uart_config.DataBits = ((data_bits == 7) ? UART_DATA_BITS_7: - ((data_bits == 8) ? UART_DATA_BITS_8 : UART_DATA_BITS_9)); + ((data_bits == 8) ? UART_DATA_BITS_8 : UART_DATA_BITS_9)); obj->uart_config.StopBits = ((stop_bits == 1) ? UART_STOP_BITS_1 : UART_STOP_BITS_2); obj->uart_config.Parity = ((parity == ParityOdd) ? UART_ODD_PARITY : - ((parity == ParityEven) ? UART_EVEN_PARITY : UART_NO_PARITY)); + ((parity == ParityEven) ? UART_EVEN_PARITY : UART_NO_PARITY)); UART_Init(obj->UARTx,&obj->uart_config); break; case SERIAL_4: @@ -244,12 +248,14 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b obj->fuart_config.DataBits = ((data_bits == 7) ? FUART_DATA_BITS_7 : FUART_DATA_BITS_8); obj->fuart_config.StopBits = ((stop_bits == 1) ? FUART_STOP_BITS_1 : FUART_STOP_BITS_2); obj->fuart_config.Parity = ((parity == ParityOdd) ? FUART_ODD_PARITY : - ((parity == ParityEven) ? FUART_EVEN_PARITY : - ((parity == ParityForced1) ? FUART_1_PARITY : - ((parity == ParityForced0) ? FUART_0_PARITY : FUART_NO_PARITY)))); + ((parity == ParityEven) ? FUART_EVEN_PARITY : + ((parity == ParityForced1) ? FUART_1_PARITY : + ((parity == ParityForced0) ? FUART_0_PARITY : FUART_NO_PARITY)))); FUART_Init(obj->FUART,&obj->fuart_config); FUART_Enable(obj->FUART); break; + default: + break; } } @@ -363,6 +369,8 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) case SERIAL_5: irq_n = INTUART1_IRQn; break; + default: + break; } if ((obj->index == SERIAL_4) || (obj->index == SERIAL_5)) { @@ -428,6 +436,8 @@ void serial_putc(serial_t *obj, int c) case SERIAL_5: FUART_SetTxData(obj->FUART,(uint32_t)c); break; + default: + break; } } @@ -440,7 +450,7 @@ int serial_readable(serial_t *obj) case SERIAL_1: case SERIAL_2: case SERIAL_3: - if(UART_GetBufState(obj->UARTx, UART_RX) == DONE) { + if (UART_GetBufState(obj->UARTx, UART_RX) == DONE) { ret = 1; } break; @@ -450,6 +460,8 @@ int serial_readable(serial_t *obj) ret = 1; } break; + default: + break; } return ret; } @@ -463,7 +475,7 @@ int serial_writable(serial_t *obj) case SERIAL_1: case SERIAL_2: case SERIAL_3: - if(UART_GetBufState(obj->UARTx, UART_TX) == DONE) { + if (UART_GetBufState(obj->UARTx, UART_TX) == DONE) { ret = 1; } break; @@ -473,6 +485,8 @@ int serial_writable(serial_t *obj) ret = 1; } break; + default: + break; } return ret; } @@ -490,6 +504,8 @@ void serial_clear(serial_t *obj) case SERIAL_5: FUART_GetRxData(obj->FUART); break; + default: + break; } } @@ -545,9 +561,9 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi // Enable the pin for CTS and RTS function if (uart_name == SERIAL_5) { pinmap_pinout(txflow, &PinMap_UART_CTS[5]); - } else { + } else { pinmap_pinout(txflow, PinMap_UART_CTS); - } + } } else if (type == FlowControlRTS) { MBED_ASSERT(uart_rts != (UARTName) NC); @@ -565,9 +581,9 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi // Enable the pin for CTS and RTS function if (uart_name == SERIAL_5) { pinmap_pinout(txflow, &PinMap_UART_CTS[5]); - } else { + } else { pinmap_pinout(txflow, PinMap_UART_CTS); - } + } pinmap_pinout(rxflow, PinMap_UART_RTS); } else { // Disable CTS and RTS hardware flow control @@ -575,6 +591,8 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi } FUART_Enable(obj->FUART); break; + default: + break; } } diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/spi_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/spi_api.c index 68b4231bca..bd98132b0b 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/spi_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/spi_api.c @@ -32,6 +32,17 @@ #include "pinmap.h" #include "tmpm46b_ssp.h" +#define TMPM46B_SPI_2_FMAX 20000000 +#define TMPM46B_SPI_FMAX 10000000 +#define SPI_TRANSFER_STATE_IDLE (0U) +#define SPI_TRANSFER_STATE_BUSY (1U) + +#if DEVICE_SPI_ASYNCH +#define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else +#define SPI_S(obj) (( struct spi_s *)(obj)) +#endif + static const PinMap PinMap_SPI_SCLK[] = { {PK4, SPI_0, PIN_DATA(2, 1)}, {PF3, SPI_1, PIN_DATA(5, 1)}, @@ -39,6 +50,13 @@ static const PinMap PinMap_SPI_SCLK[] = { {NC, NC, 0} }; +static const PinMap PinMap_SPI_SLAVE_SCLK[] = { + {PK4, SPI_0, PIN_DATA(2, 0)}, + {PF3, SPI_1, PIN_DATA(5, 0)}, + {PD3, SPI_2, PIN_DATA(1, 0)}, + {NC, NC, 0} +}; + static const PinMap PinMap_SPI_MOSI[] = { {PK3, SPI_0, PIN_DATA(2, 1)}, {PF4, SPI_1, PIN_DATA(5, 1)}, @@ -54,17 +72,19 @@ static const PinMap PinMap_SPI_MISO[] = { }; static const PinMap PinMap_SPI_SSEL[] = { - {PK1, SPI_0, PIN_DATA(2, 1)}, - {PF6, SPI_1, PIN_DATA(5, 1)}, - {PD0, SPI_2, PIN_DATA(1, 1)}, + {PK1, SPI_0, PIN_DATA(2, 2)}, + {PF6, SPI_1, PIN_DATA(5, 2)}, + {PD0, SPI_2, PIN_DATA(1, 2)}, {NC, NC, 0} }; -#define TMPM46B_SPI_2_FMAX 20000000 -#define TMPM46B_SPI_FMAX 10000000 +#if DEVICE_SPI_ASYNCH +static inline void state_idle(struct spi_s *obj_s); +#endif void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + struct spi_s *obj_s = SPI_S(obj); SSP_InitTypeDef config; // Check pin parameters @@ -75,24 +95,32 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - obj->module = (SPIName)pinmap_merge(spi_data, spi_sclk); - obj->module = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT((int)obj->module!= NC); + obj_s->module = (SPIName)pinmap_merge(spi_data, spi_sclk); + obj_s->module = (SPIName)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj_s->module!= NC); + + obj_s->clk_pin = sclk; +#if DEVICE_SPI_ASYNCH + obj_s->state = SPI_TRANSFER_STATE_IDLE; +#endif // Identify SPI module to use - switch ((int)obj->module) { + switch ((int)obj_s->module) { case SPI_0: - obj->spi = TSB_SSP0; + obj_s->irqn = INTSSP0_IRQn; + obj_s->spi = TSB_SSP0; break; case SPI_1: - obj->spi = TSB_SSP1; + obj_s->irqn = INTSSP1_IRQn; + obj_s->spi = TSB_SSP1; break; case SPI_2: - obj->spi = TSB_SSP2; + obj_s->irqn = INTSSP2_IRQn; + obj_s->spi = TSB_SSP2; break; default: - obj->spi= NULL; - obj->module = (SPIName)NC; + obj_s->spi= NULL; + obj_s->module = (SPIName)NC; error("Cannot found SPI module corresponding with input pins."); break; } @@ -117,33 +145,40 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel config.ClkPhase = SSP_PHASE_FIRST_EDGE; config.DataSize = 0x08; - obj->bits = config.DataSize; + obj_s->bits = config.DataSize; config.Mode = SSP_MASTER; - SSP_Init(obj->spi, &config); + SSP_Init(obj_s->spi, &config); // Disable all interrupt - SSP_SetINTConfig(obj->spi, SSP_INTCFG_NONE); - SSP_Enable(obj->spi); + SSP_SetINTConfig(obj_s->spi, SSP_INTCFG_NONE); + SSP_Enable(obj_s->spi); } void spi_free(spi_t *obj) { - SSP_Disable(obj->spi); - obj->spi = NULL; - obj->module = (SPIName)NC; + struct spi_s *obj_s = SPI_S(obj); + SSP_Disable(obj_s->spi); + obj_s->spi = NULL; + obj_s->module = (SPIName)NC; } void spi_format(spi_t *obj, int bits, int mode, int slave) { + struct spi_s *obj_s = SPI_S(obj); TSB_SSP_TypeDef* spi; - MBED_ASSERT(slave == SSP_MASTER); // Master mode only + MBED_ASSERT((slave == SSP_MASTER) || (slave == SSP_SLAVE)); - spi = obj->spi; + spi = obj_s->spi; SSP_Disable(spi); - obj->bits = bits; + if (slave) { + pinmap_pinout(obj_s->clk_pin, PinMap_SPI_SLAVE_SCLK); + SSP_SetMSMode(spi, SSP_SLAVE); + } + + obj_s->bits = bits; SSP_SetDataSize(spi, bits); SSP_SetClkPolarity(spi, (SSP_ClkPolarity)(mode & 0x1)); @@ -154,6 +189,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) void spi_frequency(spi_t *obj, int hz) { + struct spi_s *obj_s = SPI_S(obj); TSB_SSP_TypeDef* spi; // Search Freq data @@ -174,13 +210,13 @@ void spi_frequency(spi_t *obj, int hz) */ MBED_ASSERT((SystemCoreClock / 65024) <= (uint32_t)hz); - if (obj->module == SPI_2) { + if (obj_s->module == SPI_2) { MBED_ASSERT(hz <= TMPM46B_SPI_2_FMAX); } else { MBED_ASSERT(hz <= TMPM46B_SPI_FMAX); // Default value of SPI_0, SPI_1, SPI_2 } - spi = obj->spi; + spi = obj_s->spi; fr_gear = SystemCoreClock / hz; if (fr_gear < 48) { cur_cpsdvsr = fr_gear; @@ -239,9 +275,10 @@ static void spi_clear_FIFOs(TSB_SSP_TypeDef *spi) int spi_master_write(spi_t *obj, int value) { + struct spi_s *obj_s = SPI_S(obj); TSB_SSP_TypeDef* spi; - spi = obj->spi; + spi = obj_s->spi; // Clear all data in transmit FIFO and receive FIFO spi_clear_FIFOs(spi); // Transmit data @@ -270,16 +307,64 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, return total; } +int spi_slave_receive(spi_t *obj) +{ + struct spi_s *obj_s = SPI_S(obj); + SSP_FIFOState rx_buf_state; + TSB_SSP_TypeDef* spi; + + spi = obj_s->spi; + + rx_buf_state = SSP_GetFIFOState(spi, SSP_RX); + + if ((rx_buf_state == SSP_FIFO_NORMAL) || (rx_buf_state == SSP_FIFO_FULL)) { + return 1; + } + + return 0; +} + +int spi_slave_read(spi_t *obj) +{ + struct spi_s *obj_s = SPI_S(obj); + uint8_t ret_value = 0; + TSB_SSP_TypeDef* spi; + + spi = obj_s->spi; + + ret_value = SSP_GetRxData(spi); + + SSP_Disable(spi); + + return ret_value; +} + +void spi_slave_write(spi_t *obj, int value) +{ + struct spi_s *obj_s = SPI_S(obj); + TSB_SSP_TypeDef* spi; + + spi = obj_s->spi; + + SSP_SetTxData(spi, value); + + SSP_Enable(spi); +} int spi_busy(spi_t *obj) { + struct spi_s *obj_s = SPI_S(obj); WorkState state; - state = SSP_GetWorkState(obj->spi); + + state = SSP_GetWorkState(obj_s->spi); + return (state == BUSY); } uint8_t spi_get_module(spi_t *obj) { - return (uint8_t)(obj->module); + struct spi_s *obj_s = SPI_S(obj); + + return (uint8_t)(obj_s->module); } const PinMap *spi_master_mosi_pinmap() @@ -321,3 +406,154 @@ const PinMap *spi_slave_cs_pinmap() { return PinMap_SPI_SSEL; } + +#ifdef DEVICE_SPI_ASYNCH + +void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, + uint32_t handler, uint32_t event, DMAUsage hint) +{ + struct spi_s *obj_s = SPI_S(obj); + TSB_SSP_TypeDef* spi; + + spi = obj_s->spi; + + obj_s->event_mask = event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; + + // check which use-case we have + bool use_tx = (tx != NULL && tx_length > 0); + bool use_rx = (rx != NULL && rx_length > 0); + + // don't do anything, if the buffers aren't valid + if (!use_tx && !use_rx) { + return; + } + + // copy the buffers to the SPI object + obj->tx_buff.buffer = (void *) tx; + obj->tx_buff.length = tx ? tx_length : 0; + obj->tx_buff.pos = 0; + + obj->rx_buff.buffer = rx; + obj->rx_buff.length = rx ? rx_length : 0; + obj->rx_buff.pos = 0; + + NVIC_SetVector(obj_s->irqn, (uint32_t)handler); //receive interrupt + NVIC_ClearPendingIRQ(obj_s->irqn); + + obj_s->state = SPI_TRANSFER_STATE_BUSY; + + SSP_SetINTConfig(spi, SSP_INTCFG_ALL); + + if (use_tx) { + // Transmit first byte to enter into handler + SSP_SetTxData(spi, *(uint8_t *)(tx)); + obj->tx_buff.pos++; + } else if (use_rx) { + //if RX only then transmit one dummy byte to enter into handler + SSP_SetTxData(spi, 0xFF); + } + + SSP_Enable(spi); + NVIC_EnableIRQ(obj_s->irqn); +} + +uint32_t spi_irq_handler_asynch(spi_t *obj) +{ + struct spi_s *obj_s = SPI_S(obj); + TSB_SSP_TypeDef* spi; + int event = 0; + SSP_INTState state = { 0U }; + + spi = obj_s->spi; + + if (obj_s->state != SPI_TRANSFER_STATE_BUSY) { + event = SPI_EVENT_ERROR | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; + state_idle(obj_s); + return (event & obj_s->event_mask); + } + + state = SSP_GetPostEnableINTState(spi); + + if (state.Bit.TimeOut || state.Bit.Rx) { + + if (obj->rx_buff.pos < obj->rx_buff.length) { + *((uint8_t *)obj->rx_buff.buffer + obj->rx_buff.pos) = (uint8_t)SSP_GetRxData(spi); + obj->rx_buff.pos++; + + if ((obj->tx_buff.pos == obj->tx_buff.length) && (obj->rx_buff.pos < obj->rx_buff.length)) { + // transmit complete but receive pending - dummy write + SSP_SetTxData(spi, 0xFF); + } + + } else { + //Receive complete - dummy read + uint8_t dummy = (uint8_t)SSP_GetRxData(spi); + (void)dummy; + } + } + + if (state.Bit.Tx) { + + if (obj->tx_buff.pos < obj->tx_buff.length) { + SSP_SetTxData(spi, (*((uint8_t *)obj->tx_buff.buffer + obj->tx_buff.pos) & 0xFF)); + obj->tx_buff.pos++; + + } else if (obj->rx_buff.pos == obj->rx_buff.length) { + // Tx and Rx complete + event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; + state_idle(obj_s); + } + } + + if (state.Bit.OverRun) { + SSP_ClearINTFlag(spi, SSP_INTCFG_ALL); + event = SPI_EVENT_ERROR | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; + state_idle(obj_s); + } + + return (event & obj_s->event_mask); +} + +uint8_t spi_active(spi_t *obj) +{ + struct spi_s *obj_s = SPI_S(obj); + + return (obj_s->state != SPI_TRANSFER_STATE_IDLE); +} + +void spi_abort_asynch(spi_t *obj) +{ + struct spi_s *obj_s = SPI_S(obj); + SSP_InitTypeDef config; + + state_idle(obj_s); + + config.FrameFormat = SSP_FORMAT_SPI; + + // bit_rate = Fsys / (clk_prescale * (clk_rate + 1)) + config.PreScale = 48; + config.ClkRate = 0; + + config.ClkPolarity = SSP_POLARITY_LOW; + config.ClkPhase = SSP_PHASE_FIRST_EDGE; + config.DataSize = obj_s->bits; + + config.Mode = SSP_MASTER; + + SSP_Init(obj_s->spi, &config); + SSP_Enable(obj_s->spi); +} + +static inline void state_idle(struct spi_s *obj_s) +{ + NVIC_DisableIRQ(obj_s->irqn); + NVIC_ClearPendingIRQ(obj_s->irqn); + obj_s->state = SPI_TRANSFER_STATE_IDLE; + + //clean-up + spi_clear_FIFOs(obj_s->spi); + SSP_Disable(obj_s->spi); + SSP_ClearINTFlag(obj_s->spi, SSP_INTCFG_ALL); +} + +#endif //DEVICE_SPI_ASYNCH diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/trng_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/trng_api.c index 8e0eb56181..fbb44918a8 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/trng_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/trng_api.c @@ -28,7 +28,7 @@ static Result ESG_Config(void) if (ESG_GetIntStatus() == DISABLE) { // Set the latch timing & output timing if ((ESG_SetLatchTiming(ESG_LATCH_TIMING_1) == SUCCESS) && - (ESG_SetFintiming(Fintming) == SUCCESS)) { + (ESG_SetFintiming(Fintming) == SUCCESS)) { ret = SUCCESS; } } @@ -67,7 +67,7 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l if (!obj->trng_init) { error("TRNG is not Initialised"); - return FAIL; // fail i.e. -1 + return FAIL; // fail i.e. -1 } while (ESG_GetIntStatus() == DISABLE) { @@ -76,7 +76,7 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l // Interrupt clearing ret = ESG_ClrInt(); if (ret == ERROR) { - return FAIL; // fail i.e. -1 + return FAIL; // fail i.e. -1 } // Get the calculation result ESG_GetResult((uint32_t*)random); //512-bit entropy diff --git a/targets/targets.json b/targets/targets.json index 4393807897..3779191350 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -8232,10 +8232,15 @@ "PORTOUT", "PWMOUT", "RESET_REASON", + "RTC", "SERIAL", "SERIAL_FC", "SPI", + "SPISLAVE", + "SPI_ASYNCH", "I2C", + "I2CSLAVE", + "I2C_ASYNCH", "STDIO_MESSAGES", "TRNG", "FLASH",