summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsp/efm32/dev_led.h2
-rw-r--r--bsp/efm32/dev_misc.c8
-rw-r--r--bsp/efm32/drv_acmp.c7
-rw-r--r--bsp/efm32/drv_acmp.h6
-rw-r--r--bsp/efm32/drv_adc.c5
-rw-r--r--bsp/efm32/drv_iic.c334
-rw-r--r--bsp/efm32/drv_iic.h22
-rw-r--r--bsp/efm32/drv_rtc.c5
-rw-r--r--bsp/efm32/drv_timer.c67
-rw-r--r--bsp/efm32/drv_usart.c15
-rw-r--r--bsp/efm32/drv_usart.h6
-rw-r--r--bsp/efm32/hdl_interrupt.c57
-rw-r--r--bsp/efm32/hdl_interrupt.h3
-rw-r--r--bsp/efm32/rtconfig.h20
14 files changed, 485 insertions, 72 deletions
diff --git a/bsp/efm32/dev_led.h b/bsp/efm32/dev_led.h
index de37b75bd7..14b6ccc1f3 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 2f7ccf50a9..ac77e3b8eb 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 ab56463014..d44a7dd4e3 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 47a56242b9..530fcd32b2 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 f417a4b408..c2e08dfc25 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 0cd7538e5f..6060135e5b 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;
}
@@ -76,6 +81,61 @@ static rt_err_t rt_iic_init (rt_device_t dev)
/******************************************************************//**
* @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
*
* @details
@@ -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;
@@ -374,6 +536,83 @@ rt_err_t rt_hw_iic_register(
}
/******************************************************************//**
+ * @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 2ef227a01d..2c9d2f723a 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 1706c11e1d..da8ecfc3ed 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 a532588419..061e3e51a3 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 51bbe861cc..2119af6860 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 2a2d8ba5d4..134b094c3c 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 cd4b8871a3..ea8e388909 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 ---------------------------------------------------------*/
@@ -183,6 +184,31 @@ void DMA_IRQHandler_All(unsigned int channel, bool primary, void *user)
/******************************************************************//**
* @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
*
* @details
@@ -504,6 +530,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
*
* @details
@@ -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 02331a0824..13f33c947b 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 9714699074..d23f515c18 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