diff --git a/bsp/efm32/dev_led.h b/bsp/efm32/dev_led.h index de37b75bd730c20da9d7e18cc8ed13a0d7ffe768..14b6ccc1f3bd1fd65b9f9093d88f9127ca8a7331 100644 --- a/bsp/efm32/dev_led.h +++ b/bsp/efm32/dev_led.h @@ -34,7 +34,7 @@ #define LEDS_PIN_NUMBER_3 (3) #elif defined(EFM32_G290_DK) - //TODO + // TODO: #endif /* Exported functions --------------------------------------------------------- */ diff --git a/bsp/efm32/dev_misc.c b/bsp/efm32/dev_misc.c index 2f7ccf50a923a69f04195b41071ac691a6e505eb..ac77e3b8eb5f538bfae320a44de70fc5f0df2600 100644 --- a/bsp/efm32/dev_misc.c +++ b/bsp/efm32/dev_misc.c @@ -112,8 +112,10 @@ rt_err_t rt_hw_misc_init(void) adc0 = rt_device_find(RT_ADC0_NAME); if (adc0 == RT_NULL) { - rt_kprintf("Batt error: Can't find device: %s!\n", RT_ADC0_NAME); - +#ifdef RT_MISC_DEBUG + rt_kprintf("Batt err: Can't find device: %s!\n", RT_ADC0_NAME); +#endif + goto MISC_INIT_ERROR; } @@ -122,7 +124,7 @@ rt_err_t rt_hw_misc_init(void) MISC_INIT_ERROR: #ifdef RT_MISC_DEBUG - rt_kprintf("Misc error: Init failed!\n"); + rt_kprintf("Misc err: Init failed!\n"); #endif return -RT_ERROR; diff --git a/bsp/efm32/drv_acmp.c b/bsp/efm32/drv_acmp.c index ab564630140c03afa498d39b908b7fe4779c6da0..d44a7dd4e30bf2c4964a70b51805845369b52de2 100644 --- a/bsp/efm32/drv_acmp.c +++ b/bsp/efm32/drv_acmp.c @@ -116,7 +116,10 @@ static rt_err_t rt_acmp_control( { rt_bool_t int_en = false; +#ifdef RT_ACMP_DEBUG rt_kprintf("ACMP: control -> init start\n"); +#endif + /* change device setting */ struct efm32_acmp_control_t *control; @@ -257,7 +260,9 @@ void rt_hw_acmp_init(void) acmp = rt_malloc(sizeof(struct efm32_acmp_device_t)); if (acmp == RT_NULL) { +#ifdef RT_ACMP_DEBUG rt_kprintf("no memory for ACMP0 driver\n"); +#endif return; } acmp->acmp_device = ACMP0; @@ -281,7 +286,9 @@ void rt_hw_acmp_init(void) acmp = rt_malloc(sizeof(struct efm32_acmp_device_t)); if (acmp == RT_NULL) { +#ifdef RT_ACMP_DEBUG rt_kprintf("no memory for ACMP1 driver\n"); +#endif return; } acmp->acmp_device = ACMP1; diff --git a/bsp/efm32/drv_acmp.h b/bsp/efm32/drv_acmp.h index 47a56242b9e2fc6ea4210a3c11c186c7e502853d..530fcd32b2fe1e28df303aadb68e533a4cfb6a83 100644 --- a/bsp/efm32/drv_acmp.h +++ b/bsp/efm32/drv_acmp.h @@ -50,12 +50,12 @@ struct efm32_acmp_control_t false, /* Full bias current*/ \ true, /* Half bias current */ \ 0, /* Biasprog current configuration */ \ - false, /* Enable interrupt for falling edge */ \ - false, /* Enable interrupt for rising edge */ \ + true, /* Enable interrupt for falling edge */ \ + true, /* Enable interrupt for rising edge */ \ acmpWarmTime512, /* Warm-up time must be >10us */ \ acmpHysteresisLevel0, /* Hysteresis configuration */ \ 0, /* Inactive comparator output value */ \ - false, /* Enable low power mode */ \ + false, /* Disable low power mode */ \ 0 /* Vdd reference scaling */ \ } diff --git a/bsp/efm32/drv_adc.c b/bsp/efm32/drv_adc.c index f417a4b4087cb558d49166e39ead6569a87e2d9a..c2e08dfc258b9d75c985170560db518e527168f2 100644 --- a/bsp/efm32/drv_adc.c +++ b/bsp/efm32/drv_adc.c @@ -253,7 +253,8 @@ void rt_hw_adc_init(void) struct efm32_adc_device_t *adc; ADC_Init_TypeDef init = ADC_INIT_DEFAULT; - init.ovsRateSel = adcOvsRateSel4096; //TODO + // TODO: Fixed oversampling rate? + init.ovsRateSel = adcOvsRateSel4096; init.timebase = ADC_TimebaseCalc(0); init.prescale = ADC_PrescaleCalc(ADC_CONVERT_FREQUENCY, 0); @@ -262,7 +263,9 @@ void rt_hw_adc_init(void) adc = rt_malloc(sizeof(struct efm32_adc_device_t)); if (adc == RT_NULL) { +#ifdef RT_ADC_DEBUG rt_kprintf("no memory for ADC driver\n"); +#endif return; } adc->adc_device = ADC0; diff --git a/bsp/efm32/drv_iic.c b/bsp/efm32/drv_iic.c index 0cd7538e5f662124ed6e749f9aa3921f356db804..6060135e5bd2e8255193095cac2f71dd9bd0f215 100644 --- a/bsp/efm32/drv_iic.c +++ b/bsp/efm32/drv_iic.c @@ -21,6 +21,7 @@ /* Includes -------------------------------------------------------------------*/ #include "board.h" +#include "hdl_interrupt.h" #include "drv_iic.h" /* Private typedef -------------------------------------------------------------*/ @@ -32,13 +33,15 @@ #error "The location number range of IIC is 0~3" #endif struct rt_device iic0_device; + static struct rt_device iic0_rx_index; #endif #ifdef RT_USING_IIC1 #if (RT_USING_IIC1 > 3) #error "The location number range of IIC is 0~3" #endif - struct rt_device iic1_device; + struct rt_device iic1_device; + static struct rt_device iic1_rx_index; #endif /* Private function prototypes ---------------------------------------------------*/ @@ -67,6 +70,8 @@ static rt_err_t rt_iic_init (rt_device_t dev) { /* Enable IIC */ I2C_Enable(iic->iic_device, true); + iic->rx_buffer = RT_NULL; + iic->state = 0; dev->flag |= RT_DEVICE_FLAG_ACTIVATED; } @@ -74,6 +79,61 @@ static rt_err_t rt_iic_init (rt_device_t dev) return RT_EOK; } +/******************************************************************//** + * @brief + * Open IIC device + * + * @details + * + * @note + * + * @param[in] dev + * Pointer to device descriptor + * + * @param[in] oflag + * Device open flag + * + * @return + * Error code + *********************************************************************/ +static rt_err_t rt_iic_open(rt_device_t dev, rt_uint16_t oflag) +{ + RT_ASSERT(dev != RT_NULL); + +#ifdef RT_IIC_DEBUG + rt_kprintf("IIC: Open with flag %x\n", oflag); +#endif + + return RT_EOK; +} + +/******************************************************************//** + * @brief + * Close IIC device + * + * @details + * + * @note + * + * @param[in] dev + * Pointer to device descriptor + * + * @return + * Error code + *********************************************************************/ +static rt_err_t rt_iic_close(rt_device_t dev) +{ + struct efm32_iic_device_t *iic; + + iic = (struct efm32_iic_device_t *)(dev->user_data); + + rt_free(iic->rx_buffer->data_ptr); + rt_free(iic->rx_buffer); + iic->rx_buffer = RT_NULL; + + return RT_EOK; +} + /******************************************************************//** * @brief * Read from IIC device @@ -120,7 +180,7 @@ static rt_size_t rt_iic_read ( iic = (struct efm32_iic_device_t*)dev->user_data; data[0] = (rt_uint8_t)(pos & 0x000000FF); - if (iic->is_master) + if (iic->state & IIC_STATE_MASTER) { seq.addr = iic->slave_address; seq.flags = I2C_FLAG_WRITE_READ; @@ -130,37 +190,82 @@ static rt_size_t rt_iic_read ( /* Select location/length of data to be read */ seq.buf[1].data = (rt_uint8_t *)buffer; seq.buf[1].len = size; - } - else - { - //TODO - } - - /* Do a polled transfer */ - ret = I2C_TransferInit(iic->iic_device, &seq); - while (ret == i2cTransferInProgress) - { - ret = I2C_Transfer(iic->iic_device); - } - if (ret != i2cTransferDone) - { + /* Do a polled transfer */ + ret = I2C_TransferInit(iic->iic_device, &seq); + while (ret == i2cTransferInProgress) + { + ret = I2C_Transfer(iic->iic_device); + } + + if (ret != i2cTransferDone) + { #ifdef RT_IIC_DEBUG - rt_kprintf("IIC0 read error: %x\n", ret); - rt_kprintf("IIC0 read address: %x\n", seq.addr); - rt_kprintf("IIC0 read data0: %x -> %x\n", seq.buf[0].data, *seq.buf[0].data); - rt_kprintf("IIC0 read len0: %x\n", seq.buf[0].len); - rt_kprintf("IIC0 read data1: %x -> %x\n", seq.buf[1].data, *seq.buf[1].data); - rt_kprintf("IIC0 read len1: %x\n", seq.buf[1].len); + rt_kprintf("IIC0 read error: %x\n", ret); + rt_kprintf("IIC0 read address: %x\n", seq.addr); + rt_kprintf("IIC0 read data0: %x -> %x\n", seq.buf[0].data, *seq.buf[0].data); + rt_kprintf("IIC0 read len0: %x\n", seq.buf[0].len); + rt_kprintf("IIC0 read data1: %x -> %x\n", seq.buf[1].data, *seq.buf[1].data); + rt_kprintf("IIC0 read len1: %x\n", seq.buf[1].len); #endif - err_code = (rt_err_t)ret; + err_code = (rt_err_t)ret; + } + else + { + read_size = size; +#ifdef RT_IIC_DEBUG + rt_kprintf("IIC0 read size: %d\n", read_size); +#endif + } } else { + rt_uint8_t* ptr; + + ptr = buffer; + + /* interrupt mode Rx */ + while (size) + { + rt_base_t level; + struct efm32_iic_int_mode_t *int_rx; + + int_rx = iic->rx_buffer; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + if (int_rx->read_index != int_rx->save_index) + { + /* read a character */ + *ptr++ = int_rx->data_ptr[int_rx->read_index]; + size--; + + /* move to next position */ + int_rx->read_index ++; + if (int_rx->read_index >= IIC_RX_BUFFER_SIZE) + { + int_rx->read_index = 0; + } + } + else + { + /* set error code */ + err_code = -RT_EEMPTY; + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + break; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } + + read_size = (rt_uint32_t)ptr - (rt_uint32_t)buffer; #ifdef RT_IIC_DEBUG - rt_kprintf("IIC0 read size: %d\n", size); + rt_kprintf("IIC0 slave read size: %d\n", read_size); #endif - read_size = size; } /* set error code */ @@ -214,7 +319,7 @@ static rt_size_t rt_iic_write ( iic = (struct efm32_iic_device_t*)dev->user_data; //data[0] = (rt_uint8_t)(pos & 0x000000FF); - if (iic->is_master) + if (iic->state & IIC_STATE_MASTER) { seq.addr = iic->slave_address; if (pos != (rt_off_t)(-1)) @@ -237,7 +342,7 @@ static rt_size_t rt_iic_write ( } else { - //TODO + // TODO: Slave mode TX } /* Do a polled transfer */ @@ -311,9 +416,66 @@ static rt_err_t rt_iic_control ( struct efm32_iic_control_t *control; control = (struct efm32_iic_control_t *)args; - iic->is_master = control->is_master; + iic->state = control->config & (IIC_STATE_MASTER | IIC_STATE_BROADCAST); iic->master_address = control->master_address << 1; iic->slave_address = control->slave_address << 1; + + if (!(iic->state & IIC_STATE_MASTER)) + { + if (iic->rx_buffer == RT_NULL) + { + iic->rx_buffer = rt_malloc(sizeof(struct efm32_iic_int_mode_t)); + if (iic->rx_buffer == RT_NULL) + { +#ifdef RT_IIC_DEBUG + rt_kprintf("no memory for IIC RX structure\n"); +#endif + return -RT_ENOMEM; + } + + /* Allocate RX buffer */ + if ((iic->rx_buffer->data_ptr = \ + rt_malloc(IIC_RX_BUFFER_SIZE)) == RT_NULL) + { +#ifdef RT_IIC_DEBUG + rt_kprintf("no memory for IIC RX buffer\n"); +#endif + rt_free(iic->rx_buffer); + return -RT_ENOMEM; + } + rt_memset(iic->rx_buffer->data_ptr, 0, IIC_RX_BUFFER_SIZE); + iic->rx_buffer->data_size = IIC_RX_BUFFER_SIZE; + iic->rx_buffer->read_index = 0; + iic->rx_buffer->save_index = 0; + } + + /* Enable slave mode */ + I2C_SlaveAddressSet(iic->iic_device, iic->slave_address); + I2C_SlaveAddressMaskSet(iic->iic_device, 0xFF); + iic->iic_device->CTRL |= I2C_CTRL_SLAVE | I2C_CTRL_AUTOACK | I2C_CTRL_AUTOSN; + + /* Enable interrupts */ + I2C_IntEnable(iic->iic_device, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP); + I2C_IntClear(iic->iic_device, _I2C_IFC_MASK); + + /* Enable I2Cn interrupt vector in NVIC */ +#ifdef RT_USING_IIC0 + if (dev == &iic0_device) + { + NVIC_ClearPendingIRQ(I2C0_IRQn); + NVIC_SetPriority(I2C0_IRQn, EFM32_IRQ_PRI_DEFAULT); + NVIC_EnableIRQ(I2C0_IRQn); + } +#endif +#ifdef RT_USING_IIC1 + if (dev == &iic1_device) + { + NVIC_ClearPendingIRQ(I2C1_IRQn); + NVIC_SetPriority(I2C1_IRQn, EFM32_IRQ_PRI_DEFAULT); + NVIC_EnableIRQ(I2C1_IRQn); + } +#endif + } } break; } @@ -353,7 +515,7 @@ rt_err_t rt_hw_iic_register( RT_ASSERT(device != RT_NULL); if ((flag & RT_DEVICE_FLAG_DMA_TX) || (flag & RT_DEVICE_FLAG_DMA_RX) || - (flag & RT_DEVICE_FLAG_INT_TX) || (flag & RT_DEVICE_FLAG_INT_RX)) + (flag & RT_DEVICE_FLAG_INT_TX)) { RT_ASSERT(0); } @@ -362,8 +524,8 @@ rt_err_t rt_hw_iic_register( device->rx_indicate = RT_NULL; device->tx_complete = RT_NULL; device->init = rt_iic_init; - device->open = RT_NULL; - device->close = RT_NULL; + device->open = rt_iic_open; + device->close = rt_iic_close; device->read = rt_iic_read; device->write = rt_iic_write; device->control = rt_iic_control; @@ -373,6 +535,83 @@ rt_err_t rt_hw_iic_register( return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); } +/******************************************************************//** + * @brief + * IIC slave mode RX data valid interrupt handler + * + * @details + * + * @note + * + * @param[in] dev + * Pointer to device descriptor + *********************************************************************/ +static void rt_hw_iic_slave_isr(rt_device_t dev) +{ + struct efm32_iic_device_t *iic; + struct efm32_iic_int_mode_t *int_rx; + rt_uint32_t status; + volatile rt_uint32_t temp; + + /* interrupt mode receive */ + RT_ASSERT(dev->flag & RT_DEVICE_FLAG_INT_RX); + + iic = (struct efm32_iic_device_t*)dev->user_data; + int_rx = iic->rx_buffer; + status = iic->iic_device->IF; + + if (status & I2C_IF_ADDR) + { + /* Address Match */ + /* Indicating that reception is started */ + temp = iic->iic_device->RXDATA & 0xFFUL; + if ((temp != 0x00) || (iic->state & IIC_STATE_BROADCAST)) + { + iic->state |= IIC_STATE_RX_BUSY; + } + } + else if (status & I2C_IF_RXDATAV) + { + if (iic->state & IIC_STATE_RX_BUSY) + { + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + /* save character */ + int_rx->data_ptr[int_rx->save_index] = \ + (rt_uint8_t)(iic->iic_device->RXDATA & 0xFFUL); + int_rx->save_index ++; + if (int_rx->save_index >= IIC_RX_BUFFER_SIZE) + int_rx->save_index = 0; + + /* if the next position is read index, discard this 'read char' */ + if (int_rx->save_index == int_rx->read_index) + { + int_rx->read_index ++; + if (int_rx->read_index >= IIC_RX_BUFFER_SIZE) + { + int_rx->read_index = 0; + } + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } + else + { + temp = iic->iic_device->RXDATA; + } + } + + if(status & I2C_IF_SSTOP) + { + /* Stop received, reception is ended */ + iic->state &= ~(rt_uint8_t)IIC_STATE_RX_BUSY; + } +} + /******************************************************************//** * @brief * Initialize the specified IIC unit @@ -388,23 +627,27 @@ rt_err_t rt_hw_iic_register( * Pin location number *********************************************************************/ static void rt_hw_iic_unit_init( + rt_device_t device, rt_uint8_t unitNumber, rt_uint8_t location) { I2C_TypeDef *iic; CMU_Clock_TypeDef iicClock; I2C_Init_TypeDef init = I2C_INIT_DEFAULT; + efm32_irq_hook_init_t hook; switch (unitNumber) { case 0: iic = I2C0; iicClock = (CMU_Clock_TypeDef)cmuClock_I2C0; + hook.unit = 0; break; #if (I2C_COUNT > 1) case 1: - iic = I2C1; - iicClock = (CMU_Clock_TypeDef)cmuClock_I2C1; + iic = I2C1; + iicClock = (CMU_Clock_TypeDef)cmuClock_I2C1; + hook.unit = 1; break; #endif default: @@ -432,16 +675,19 @@ static void rt_hw_iic_unit_init( /* Enable SDZ and SCL pins and set location */ iic->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | \ (location << _I2C_ROUTE_LOCATION_SHIFT); + + hook.type = efm32_irq_type_iic; + hook.cbFunc = rt_hw_iic_slave_isr; + hook.userPtr = device; + efm32_irq_hook_register(&hook); + /* Initializing IIC */ init.enable = false; I2C_Init(iic, &init); /* Abort current TX data and clear TX buffers */ iic->CMD = I2C_CMD_ABORT | I2C_CMD_CLEARPC | I2C_CMD_CLEARTX; - - /* Clear previous interrupts */ - iic->IFC = _I2C_IFC_MASK; } /******************************************************************//** @@ -457,22 +703,25 @@ void rt_hw_iic_init(void) struct efm32_iic_device_t *iic; rt_uint32_t flag; - flag = RT_DEVICE_FLAG_RDWR; + flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX; /* register iic0 */ #ifdef RT_USING_IIC0 iic = rt_malloc(sizeof(struct efm32_iic_device_t)); if (iic == RT_NULL) { +#ifdef RT_IIC_DEBUG rt_kprintf("no memory for IIC0 driver\n"); +#endif return; } iic->iic_device = I2C0; - iic->is_master = true; + iic->state |= IIC_STATE_MASTER; iic->master_address = 0x0000; iic->slave_address = 0x0000; - rt_hw_iic_unit_init(0, RT_USING_IIC0); + iic->rx_buffer = RT_NULL; + rt_hw_iic_unit_init(&iic0_device, 0, RT_USING_IIC0); rt_hw_iic_register(&iic0_device, RT_IIC0_NAME, flag, iic); #endif @@ -482,15 +731,18 @@ void rt_hw_iic_init(void) iic = rt_malloc(sizeof(struct efm32_iic_device_t)); if (iic == RT_NULL) { +#ifdef RT_IIC_DEBUG rt_kprintf("no memory for IIC1 driver\n"); +#endif return; } iic->iic_device = I2C1; - iic->is_master = true; + iic->state |= IIC_STATE_MASTER; iic->master_address = 0x0000; iic->slave_address = 0x0000; - rt_hw_iic_unit_init(1, RT_USING_IIC1); + iic->rx_buffer = RT_NULL; + rt_hw_iic_unit_init(&iic1_device, 1, RT_USING_IIC1); rt_hw_iic_register(&iic1_device, RT_IIC1_NAME, flag, iic); #endif diff --git a/bsp/efm32/drv_iic.h b/bsp/efm32/drv_iic.h index 2ef227a01d6751415625fa5f138149fa5bb03c05..2c9d2f723a4721bca137405039854f832e6b5923 100644 --- a/bsp/efm32/drv_iic.h +++ b/bsp/efm32/drv_iic.h @@ -18,23 +18,41 @@ /* Includes -------------------------------------------------------------------*/ /* Exported types -------------------------------------------------------------*/ +struct efm32_iic_int_mode_t +{ + rt_uint8_t *data_ptr; + rt_uint8_t data_size; + rt_uint32_t read_index, save_index; +}; + struct efm32_iic_device_t { + /* State */ + rt_uint8_t state; + /* Pointer to IIC device structure */ I2C_TypeDef* iic_device; - rt_bool_t is_master; + /* Master address */ rt_uint16_t master_address; + /* Slave address */ rt_uint16_t slave_address; + /* RX structure */ + struct efm32_iic_int_mode_t *rx_buffer; }; struct efm32_iic_control_t { - rt_bool_t is_master; + rt_uint8_t config; rt_uint16_t master_address; rt_uint16_t slave_address; }; /* Exported constants ---------------------------------------------------------*/ /* Exported macro -------------------------------------------------------------*/ +#define IIC_STATE_MASTER (1 << 0) +#define IIC_STATE_BROADCAST (1 << 1) +//#define IIC_STATE_TX_BUSY (1 << 2) +#define IIC_STATE_RX_BUSY (1 << 3) + /* Exported functions --------------------------------------------------------- */ void rt_hw_iic_init(void); diff --git a/bsp/efm32/drv_rtc.c b/bsp/efm32/drv_rtc.c index 1706c11e1d26e67d2bd086054395d7622d7b4dce..da8ecfc3ed7cbe003aef460c52908b77194e626f 100644 --- a/bsp/efm32/drv_rtc.c +++ b/bsp/efm32/drv_rtc.c @@ -173,8 +173,9 @@ void rt_hw_rtc_init(void) rt_uint32_t reset; reset = RMU_ResetCauseGet(); - - if (reset & RMU_RSTCAUSE_PORST || reset & RMU_RSTCAUSE_EXTRST) //TODO + + // TODO: What is the current reset mode? + if (reset & RMU_RSTCAUSE_PORST || reset & RMU_RSTCAUSE_EXTRST) { RTC_Init_TypeDef rtcInit; efm32_irq_hook_init_t hook; diff --git a/bsp/efm32/drv_timer.c b/bsp/efm32/drv_timer.c index a53258841935bf48daf311bc8084920b729afa6c..061e3e51a3d6399c90be39ef027417cebe8f57d5 100644 --- a/bsp/efm32/drv_timer.c +++ b/bsp/efm32/drv_timer.c @@ -30,6 +30,9 @@ (p * (EFM32_HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000)) /* Private variables ------------------------------------------------------------*/ +#ifdef RT_USING_TIMER1 + static struct rt_device timer1_device; +#endif #ifdef RT_USING_TIMER2 static struct rt_device timer2_device; #endif @@ -113,15 +116,20 @@ static rt_err_t rt_hs_timer_control ( { /* change device setting */ struct efm32_timer_control_t *control; + rt_uint32_t running; control = (struct efm32_timer_control_t *)args; - + running = timer->timer_device->STATUS & 0x00000001; + TIMER_Enable(timer->timer_device, false); timer->timer_device->CNT = _TIMER_CNT_RESETVALUE; TIMER_TopSet(timer->timer_device, TIMER_TopCalculate(control->period)); timer->hook.cbFunc = control->hook.cbFunc; timer->hook.userPtr = control->hook.userPtr; - TIMER_Enable(timer->timer_device, true); + if (running) + { + TIMER_Enable(timer->timer_device, true); + } } break; } @@ -224,16 +232,67 @@ void rt_hw_timer_init(void) init.oneShot = false; init.sync = false; +#ifdef RT_USING_TIMER1 + timer = rt_malloc(sizeof(struct efm32_timer_device_t)); + if (timer == RT_NULL) + { +#ifdef RT_TIMER_DEBUG + rt_kprintf("no memory for TIMER1 driver\n"); +#endif + return; + } + + timer->timer_device = TIMER1; +#if (RT_USING_TIMER1 == RT_TIMER_ONCE) + init.oneShot = true; +#elif (RT_USING_TIMER1 == RT_TIMER_CONTINUE) + init.oneShot = false; +#endif + + /* Enable clock for TIMERn module */ + CMU_ClockEnable(cmuClock_TIMER1, true); + + /* Reset */ + TIMER_Reset(TIMER1); + + /* Configure TIMER */ + TIMER_Init(TIMER1, &init); + + hook.type = efm32_irq_type_timer; + hook.unit = 1; + hook.cbFunc = rt_hw_timer_isr; + hook.userPtr = &timer1_device; + efm32_irq_hook_register(&hook); + + /* Enable overflow interrupt */ + TIMER_IntEnable(TIMER1, TIMER_IF_OF); + TIMER_IntClear(TIMER1, TIMER_IF_OF); + + /* Enable TIMERn interrupt vector in NVIC */ + NVIC_ClearPendingIRQ(TIMER1_IRQn); + NVIC_SetPriority(TIMER1_IRQn, EFM32_IRQ_PRI_DEFAULT); + NVIC_EnableIRQ(TIMER1_IRQn); + + rt_hw_timer_register(&timer1_device, RT_TIMER1_NAME, 0, timer); +#endif + #ifdef RT_USING_TIMER2 timer = rt_malloc(sizeof(struct efm32_timer_device_t)); if (timer == RT_NULL) { - rt_kprintf("no memory for TIMER driver\n"); +#ifdef RT_TIMER_DEBUG + rt_kprintf("no memory for TIMER2 driver\n"); +#endif return; } timer->timer_device = TIMER2; - +#if (RT_USING_TIMER2 == RT_TIMER_ONCE) + init.oneShot = true; +#elif (RT_USING_TIMER2 == RT_TIMER_CONTINUE) + init.oneShot = false; +#endif + /* Enable clock for TIMERn module */ CMU_ClockEnable(cmuClock_TIMER2, true); diff --git a/bsp/efm32/drv_usart.c b/bsp/efm32/drv_usart.c index 51bbe861cc838c1f184648fcb2febb0002fd42c6..2119af68603923fdf5cc0283ab704b883f70acfa 100644 --- a/bsp/efm32/drv_usart.c +++ b/bsp/efm32/drv_usart.c @@ -140,7 +140,9 @@ static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag) if ((int_mode->data_ptr = rt_malloc(SERIAL_RX_BUFFER_SIZE)) == RT_NULL) { +#ifdef RT_USART_DEBUG rt_kprintf("no memory for serial RX buffer\n"); +#endif return -RT_ENOMEM; } rt_memset(int_mode->data_ptr, 0, SERIAL_RX_BUFFER_SIZE); @@ -498,10 +500,13 @@ static rt_err_t rt_usart_control ( if ((int_rx->data_ptr = rt_realloc(int_rx->data_ptr, size)) \ == RT_NULL) { +#ifdef RT_USART_DEBUG rt_kprintf("no memory for usart rx buffer\n"); +#endif return -RT_ENOMEM; } - //rt_memset(int_rx->data_ptr, 0, size); //TODO + // TODO: Is the following line necessary? + //rt_memset(int_rx->data_ptr, 0, size); } } else @@ -509,7 +514,9 @@ static rt_err_t rt_usart_control ( /* Allocate new RX buffer */ if ((int_rx->data_ptr = rt_malloc(size)) == RT_NULL) { +#ifdef RT_USART_DEBUG rt_kprintf("no memory for usart rx buffer\n"); +#endif return -RT_ENOMEM; } } @@ -726,7 +733,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init( usart = rt_malloc(sizeof(struct efm32_usart_device_t)); if (usart == RT_NULL) { +#ifdef RT_USART_DEBUG rt_kprintf("no memory for USART driver\n"); +#endif return usart; } usart->unit = unitNumber; @@ -748,7 +757,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init( usart->tx_mode = dma_mode = rt_malloc(sizeof(struct efm32_usart_dma_mode_t)); if (dma_mode == RT_NULL) { +#ifdef RT_USART_DEBUG rt_kprintf("no memory for USART TX by DMA\n"); +#endif rt_free(usart->rx_mode); rt_free(usart); usart = RT_NULL; @@ -763,7 +774,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init( usart->rx_mode = rt_malloc(sizeof(struct efm32_usart_int_mode_t)); if (usart->rx_mode == RT_NULL) { +#ifdef RT_USART_DEBUG rt_kprintf("no memory for USART RX by interrupt\n"); +#endif rt_free(usart->tx_mode); rt_free(usart); usart = RT_NULL; diff --git a/bsp/efm32/drv_usart.h b/bsp/efm32/drv_usart.h index 2a2d8ba5d4036c319288638486880422b1216bb4..134b094c3c5dce33d5698312c2c908865355c34f 100644 --- a/bsp/efm32/drv_usart.h +++ b/bsp/efm32/drv_usart.h @@ -39,16 +39,12 @@ struct efm32_usart_device_t { /* Unit number */ rt_uint8_t unit; - /* State */ - rt_uint32_t state; - + rt_uint8_t state; /* Pointer to USART device structure */ USART_TypeDef* usart_device; - /* Pointer to RX structure */ void *rx_mode; - /* Pointer to TX structure */ void *tx_mode; }; diff --git a/bsp/efm32/hdl_interrupt.c b/bsp/efm32/hdl_interrupt.c index cd4b8871a372f5660e473ebca6772f29f304fef3..ea8e388909b594435f65c6473b565688a79af731 100644 --- a/bsp/efm32/hdl_interrupt.c +++ b/bsp/efm32/hdl_interrupt.c @@ -33,6 +33,7 @@ efm32_irq_hook_t rtcCbTable[RTC_COUNT] = {RT_NULL}; efm32_irq_hook_t gpioCbTable[16] = {RT_NULL}; efm32_irq_hook_t acmpCbTable[ACMP_COUNT] = {RT_NULL}; efm32_irq_hook_t usartCbTable[USART_COUNT * 2] = {RT_NULL}; +efm32_irq_hook_t iicCbTable[I2C_COUNT] = {RT_NULL}; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ @@ -181,6 +182,31 @@ void DMA_IRQHandler_All(unsigned int channel, bool primary, void *user) rt_interrupt_leave(); } +/******************************************************************//** + * @brief + * Common Timer1 interrupt handler + * + * @details + * This function handles Timer1 counter overflow interrupt request + * + * @note + * + *********************************************************************/ +void TIMER1_IRQHandler(void) +{ + if (TIMER1->IF & TIMER_IF_OF) + { + /* invoke callback function */ + if (timerCbTable[1].cbFunc != RT_NULL) + { + (timerCbTable[1].cbFunc)(timerCbTable[1].userPtr); + } + + /* clear interrupt */ + BITBAND_Peripheral(&(TIMER1->IFC), _TIMER_IF_OF_SHIFT, 0x1UL); + } +} + /******************************************************************//** * @brief * Common Timer2 interrupt handler @@ -502,6 +528,32 @@ void USART2_RX_IRQHandler(void) } } +/******************************************************************//** + * @brief + * Common IIC0 interrupt handler + * + * @details + * This function handles IIC0 slave mode interrupt requests + * + * @note + * + *********************************************************************/ +void I2C0_IRQHandler(void) +{ + if ((I2C0->IF & I2C_IF_ADDR) || \ + (I2C0->IF & I2C_IF_RXDATAV) || \ + (I2C0->IF & I2C_IF_SSTOP)) + { + /* invoke callback function */ + if (iicCbTable[0].cbFunc != RT_NULL) + { + (iicCbTable[0].cbFunc)(iicCbTable[0].userPtr); + } + } + + I2C_IntClear(I2C0, I2C_IFC_ADDR | I2C_IFC_SSTOP); +} + /******************************************************************//** * @brief * EFM32 common interrupt handlers register function @@ -545,6 +597,11 @@ rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook) usartCbTable[hook->unit].userPtr = hook->userPtr; break; + case efm32_irq_type_iic: + iicCbTable[hook->unit].cbFunc = hook->cbFunc; + iicCbTable[hook->unit].userPtr = hook->userPtr; + break; + default: break; } diff --git a/bsp/efm32/hdl_interrupt.h b/bsp/efm32/hdl_interrupt.h index 02331a08245de0009ab5527ae0b4c50777b6d715..13f33c947bd073f4b78c877855e310a64b12c35d 100644 --- a/bsp/efm32/hdl_interrupt.h +++ b/bsp/efm32/hdl_interrupt.h @@ -25,7 +25,8 @@ enum efm32_irq_hook_type_t efm32_irq_type_timer, efm32_irq_type_gpio, efm32_irq_type_acmp, - efm32_irq_type_usart + efm32_irq_type_usart, + efm32_irq_type_iic }; typedef void (*efm32_irq_callback_t)(rt_device_t device); diff --git a/bsp/efm32/rtconfig.h b/bsp/efm32/rtconfig.h index 9714699074dfe34a132252d1a56c7a9c24a88f5f..d23f515c184c78254e3fcaaa5fcc37546a9711c8 100644 --- a/bsp/efm32/rtconfig.h +++ b/bsp/efm32/rtconfig.h @@ -33,13 +33,16 @@ #define RT_MEM_DEBUG //#define THREAD_DEBUG //#define IRQ_DEBUG +#define RT_USING_OVERFLOW_CHECK + //#define RT_IRQHDL_DEBUG //#define RT_ADC_DEBUG -#define RT_USING_OVERFLOW_CHECK -#define RT_USART_DEBUG +//#define RT_ACMP_DEBUG +//#define RT_TIMER_DEBUG +//#define RT_USART_DEBUG /* Using Hook */ -#define RT_USING_HOOK +//#define RT_USING_HOOK /* Using Software Timer */ /* #define RT_USING_TIMER_SOFT */ @@ -52,20 +55,20 @@ #define RT_USING_SEMAPHORE /* Using Mutex */ -#define RT_USING_MUTEX +//#define RT_USING_MUTEX /* Using Event */ -#define RT_USING_EVENT +//#define RT_USING_EVENT /* Using MailBox */ -#define RT_USING_MAILBOX +//#define RT_USING_MAILBOX /* Using Message Queue */ -#define RT_USING_MESSAGEQUEUE +//#define RT_USING_MESSAGEQUEUE /* SECTION: Memory Management */ /* Using Memory Pool Management*/ -#define RT_USING_MEMPOOL +//#define RT_USING_MEMPOOL /* Using Dynamic Heap Management */ #define RT_USING_HEAP @@ -110,6 +113,7 @@ #endif /* SECTION: Console options */ +#define RT_USING_CONSOLE /* the buffer size of console*/ #define RT_CONSOLEBUF_SIZE 128