mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-07 00:59:00 +08:00
*** 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:
+1
-1
@@ -34,7 +34,7 @@
|
||||
#define LEDS_PIN_NUMBER_3 (3)
|
||||
|
||||
#elif defined(EFM32_G290_DK)
|
||||
//TODO
|
||||
// TODO:
|
||||
#endif
|
||||
|
||||
/* Exported functions --------------------------------------------------------- */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+20
-2
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user