*** 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

View File

@ -34,7 +34,7 @@
#define LEDS_PIN_NUMBER_3 (3)
#elif defined(EFM32_G290_DK)
//TODO
// TODO:
#endif
/* Exported functions --------------------------------------------------------- */

View File

@ -112,7 +112,9 @@ 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;

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;

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

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;

View File

@ -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;
/* 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);
#endif
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
{
//TODO
}
rt_uint8_t* ptr;
/* Do a polled transfer */
ret = I2C_TransferInit(iic->iic_device, &seq);
while (ret == i2cTransferInProgress)
{
ret = I2C_Transfer(iic->iic_device);
}
ptr = buffer;
if (ret != i2cTransferDone)
{
/* 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 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 slave read size: %d\n", read_size);
#endif
err_code = (rt_err_t)ret;
}
else
{
#ifdef RT_IIC_DEBUG
rt_kprintf("IIC0 read size: %d\n", 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:
@ -433,15 +676,18 @@ static void rt_hw_iic_unit_init(
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

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);

View File

@ -174,7 +174,8 @@ void rt_hw_rtc_init(void)
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;

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,15 +232,66 @@ 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);

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;

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;
};

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;
}

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);

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