*** 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
This commit is contained in:
onelife.real
2011-03-29 09:41:22 +00:00
parent 2e59147522
commit 578b245b0e
14 changed files with 486 additions and 73 deletions
+1 -1
View File
@@ -34,7 +34,7 @@
#define LEDS_PIN_NUMBER_3 (3)
#elif defined(EFM32_G290_DK)
//TODO
// TODO:
#endif
/* Exported functions --------------------------------------------------------- */
+5 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+294 -42
View File
File diff suppressed because it is too large Load Diff
+20 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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