1
0
Эх сурвалжийг харах

*** EFM32 branch ***
1. Add IIC slave mode RX by interrupt function (Now, master mode TX/RX and slave mode RX functions are done)
2. Add Timer1 configuration in timer driver
3. Modify the ACMP default initialization setting
4. Add on/off switch for debug code to reduce size

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1353 bbd45198-f89e-11dd-88c7-29a3b14d5316

onelife.real 14 жил өмнө
parent
commit
578b245b0e

+ 1 - 1
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 --------------------------------------------------------- */

+ 5 - 3
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;

+ 7 - 0
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;

+ 3 - 3
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 */ 			\
 }
 

+ 4 - 1
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;

+ 293 - 41
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

+ 20 - 2
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);
 

+ 3 - 2
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;

+ 63 - 4
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);
 

+ 14 - 1
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;

+ 1 - 5
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;
 };

+ 57 - 0
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;
 	}

+ 2 - 1
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);

+ 12 - 8
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