提交 578b245b 编写于 作者: O onelife.real

*** 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
上级 2e591475
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define LEDS_PIN_NUMBER_3 (3) #define LEDS_PIN_NUMBER_3 (3)
#elif defined(EFM32_G290_DK) #elif defined(EFM32_G290_DK)
//TODO // TODO:
#endif #endif
/* Exported functions --------------------------------------------------------- */ /* Exported functions --------------------------------------------------------- */
......
...@@ -112,8 +112,10 @@ rt_err_t rt_hw_misc_init(void) ...@@ -112,8 +112,10 @@ rt_err_t rt_hw_misc_init(void)
adc0 = rt_device_find(RT_ADC0_NAME); adc0 = rt_device_find(RT_ADC0_NAME);
if (adc0 == RT_NULL) 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; goto MISC_INIT_ERROR;
} }
...@@ -122,7 +124,7 @@ rt_err_t rt_hw_misc_init(void) ...@@ -122,7 +124,7 @@ rt_err_t rt_hw_misc_init(void)
MISC_INIT_ERROR: MISC_INIT_ERROR:
#ifdef RT_MISC_DEBUG #ifdef RT_MISC_DEBUG
rt_kprintf("Misc error: Init failed!\n"); rt_kprintf("Misc err: Init failed!\n");
#endif #endif
return -RT_ERROR; return -RT_ERROR;
......
...@@ -116,7 +116,10 @@ static rt_err_t rt_acmp_control( ...@@ -116,7 +116,10 @@ static rt_err_t rt_acmp_control(
{ {
rt_bool_t int_en = false; rt_bool_t int_en = false;
#ifdef RT_ACMP_DEBUG
rt_kprintf("ACMP: control -> init start\n"); rt_kprintf("ACMP: control -> init start\n");
#endif
/* change device setting */ /* change device setting */
struct efm32_acmp_control_t *control; struct efm32_acmp_control_t *control;
...@@ -257,7 +260,9 @@ void rt_hw_acmp_init(void) ...@@ -257,7 +260,9 @@ void rt_hw_acmp_init(void)
acmp = rt_malloc(sizeof(struct efm32_acmp_device_t)); acmp = rt_malloc(sizeof(struct efm32_acmp_device_t));
if (acmp == RT_NULL) if (acmp == RT_NULL)
{ {
#ifdef RT_ACMP_DEBUG
rt_kprintf("no memory for ACMP0 driver\n"); rt_kprintf("no memory for ACMP0 driver\n");
#endif
return; return;
} }
acmp->acmp_device = ACMP0; acmp->acmp_device = ACMP0;
...@@ -281,7 +286,9 @@ void rt_hw_acmp_init(void) ...@@ -281,7 +286,9 @@ void rt_hw_acmp_init(void)
acmp = rt_malloc(sizeof(struct efm32_acmp_device_t)); acmp = rt_malloc(sizeof(struct efm32_acmp_device_t));
if (acmp == RT_NULL) if (acmp == RT_NULL)
{ {
#ifdef RT_ACMP_DEBUG
rt_kprintf("no memory for ACMP1 driver\n"); rt_kprintf("no memory for ACMP1 driver\n");
#endif
return; return;
} }
acmp->acmp_device = ACMP1; acmp->acmp_device = ACMP1;
......
...@@ -50,12 +50,12 @@ struct efm32_acmp_control_t ...@@ -50,12 +50,12 @@ struct efm32_acmp_control_t
false, /* Full bias current*/ \ false, /* Full bias current*/ \
true, /* Half bias current */ \ true, /* Half bias current */ \
0, /* Biasprog current configuration */ \ 0, /* Biasprog current configuration */ \
false, /* Enable interrupt for falling edge */ \ true, /* Enable interrupt for falling edge */ \
false, /* Enable interrupt for rising edge */ \ true, /* Enable interrupt for rising edge */ \
acmpWarmTime512, /* Warm-up time must be >10us */ \ acmpWarmTime512, /* Warm-up time must be >10us */ \
acmpHysteresisLevel0, /* Hysteresis configuration */ \ acmpHysteresisLevel0, /* Hysteresis configuration */ \
0, /* Inactive comparator output value */ \ 0, /* Inactive comparator output value */ \
false, /* Enable low power mode */ \ false, /* Disable low power mode */ \
0 /* Vdd reference scaling */ \ 0 /* Vdd reference scaling */ \
} }
......
...@@ -253,7 +253,8 @@ void rt_hw_adc_init(void) ...@@ -253,7 +253,8 @@ void rt_hw_adc_init(void)
struct efm32_adc_device_t *adc; struct efm32_adc_device_t *adc;
ADC_Init_TypeDef init = ADC_INIT_DEFAULT; ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
init.ovsRateSel = adcOvsRateSel4096; //TODO // TODO: Fixed oversampling rate?
init.ovsRateSel = adcOvsRateSel4096;
init.timebase = ADC_TimebaseCalc(0); init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(ADC_CONVERT_FREQUENCY, 0); init.prescale = ADC_PrescaleCalc(ADC_CONVERT_FREQUENCY, 0);
...@@ -262,7 +263,9 @@ void rt_hw_adc_init(void) ...@@ -262,7 +263,9 @@ void rt_hw_adc_init(void)
adc = rt_malloc(sizeof(struct efm32_adc_device_t)); adc = rt_malloc(sizeof(struct efm32_adc_device_t));
if (adc == RT_NULL) if (adc == RT_NULL)
{ {
#ifdef RT_ADC_DEBUG
rt_kprintf("no memory for ADC driver\n"); rt_kprintf("no memory for ADC driver\n");
#endif
return; return;
} }
adc->adc_device = ADC0; adc->adc_device = ADC0;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
/* Includes -------------------------------------------------------------------*/ /* Includes -------------------------------------------------------------------*/
#include "board.h" #include "board.h"
#include "hdl_interrupt.h"
#include "drv_iic.h" #include "drv_iic.h"
/* Private typedef -------------------------------------------------------------*/ /* Private typedef -------------------------------------------------------------*/
...@@ -32,13 +33,15 @@ ...@@ -32,13 +33,15 @@
#error "The location number range of IIC is 0~3" #error "The location number range of IIC is 0~3"
#endif #endif
struct rt_device iic0_device; struct rt_device iic0_device;
static struct rt_device iic0_rx_index;
#endif #endif
#ifdef RT_USING_IIC1 #ifdef RT_USING_IIC1
#if (RT_USING_IIC1 > 3) #if (RT_USING_IIC1 > 3)
#error "The location number range of IIC is 0~3" #error "The location number range of IIC is 0~3"
#endif #endif
struct rt_device iic1_device; struct rt_device iic1_device;
static struct rt_device iic1_rx_index;
#endif #endif
/* Private function prototypes ---------------------------------------------------*/ /* Private function prototypes ---------------------------------------------------*/
...@@ -67,6 +70,8 @@ static rt_err_t rt_iic_init (rt_device_t dev) ...@@ -67,6 +70,8 @@ static rt_err_t rt_iic_init (rt_device_t dev)
{ {
/* Enable IIC */ /* Enable IIC */
I2C_Enable(iic->iic_device, true); I2C_Enable(iic->iic_device, true);
iic->rx_buffer = RT_NULL;
iic->state = 0;
dev->flag |= RT_DEVICE_FLAG_ACTIVATED; dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
} }
...@@ -74,6 +79,61 @@ static rt_err_t rt_iic_init (rt_device_t dev) ...@@ -74,6 +79,61 @@ static rt_err_t rt_iic_init (rt_device_t dev)
return RT_EOK; 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 * @brief
* Read from IIC device * Read from IIC device
...@@ -120,7 +180,7 @@ static rt_size_t rt_iic_read ( ...@@ -120,7 +180,7 @@ static rt_size_t rt_iic_read (
iic = (struct efm32_iic_device_t*)dev->user_data; iic = (struct efm32_iic_device_t*)dev->user_data;
data[0] = (rt_uint8_t)(pos & 0x000000FF); data[0] = (rt_uint8_t)(pos & 0x000000FF);
if (iic->is_master) if (iic->state & IIC_STATE_MASTER)
{ {
seq.addr = iic->slave_address; seq.addr = iic->slave_address;
seq.flags = I2C_FLAG_WRITE_READ; seq.flags = I2C_FLAG_WRITE_READ;
...@@ -130,37 +190,82 @@ static rt_size_t rt_iic_read ( ...@@ -130,37 +190,82 @@ static rt_size_t rt_iic_read (
/* Select location/length of data to be read */ /* Select location/length of data to be read */
seq.buf[1].data = (rt_uint8_t *)buffer; seq.buf[1].data = (rt_uint8_t *)buffer;
seq.buf[1].len = size; 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 #ifdef RT_IIC_DEBUG
rt_kprintf("IIC0 read error: %x\n", ret); rt_kprintf("IIC0 read error: %x\n", ret);
rt_kprintf("IIC0 read address: %x\n", seq.addr); 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 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 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 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 len1: %x\n", seq.buf[1].len);
#endif #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 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 #ifdef RT_IIC_DEBUG
rt_kprintf("IIC0 read size: %d\n", size); rt_kprintf("IIC0 slave read size: %d\n", read_size);
#endif #endif
read_size = size;
} }
/* set error code */ /* set error code */
...@@ -214,7 +319,7 @@ static rt_size_t rt_iic_write ( ...@@ -214,7 +319,7 @@ static rt_size_t rt_iic_write (
iic = (struct efm32_iic_device_t*)dev->user_data; iic = (struct efm32_iic_device_t*)dev->user_data;
//data[0] = (rt_uint8_t)(pos & 0x000000FF); //data[0] = (rt_uint8_t)(pos & 0x000000FF);
if (iic->is_master) if (iic->state & IIC_STATE_MASTER)
{ {
seq.addr = iic->slave_address; seq.addr = iic->slave_address;
if (pos != (rt_off_t)(-1)) if (pos != (rt_off_t)(-1))
...@@ -237,7 +342,7 @@ static rt_size_t rt_iic_write ( ...@@ -237,7 +342,7 @@ static rt_size_t rt_iic_write (
} }
else else
{ {
//TODO // TODO: Slave mode TX
} }
/* Do a polled transfer */ /* Do a polled transfer */
...@@ -311,9 +416,66 @@ static rt_err_t rt_iic_control ( ...@@ -311,9 +416,66 @@ static rt_err_t rt_iic_control (
struct efm32_iic_control_t *control; struct efm32_iic_control_t *control;
control = (struct efm32_iic_control_t *)args; 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->master_address = control->master_address << 1;
iic->slave_address = control->slave_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; break;
} }
...@@ -353,7 +515,7 @@ rt_err_t rt_hw_iic_register( ...@@ -353,7 +515,7 @@ rt_err_t rt_hw_iic_register(
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
if ((flag & RT_DEVICE_FLAG_DMA_TX) || (flag & RT_DEVICE_FLAG_DMA_RX) || 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); RT_ASSERT(0);
} }
...@@ -362,8 +524,8 @@ rt_err_t rt_hw_iic_register( ...@@ -362,8 +524,8 @@ rt_err_t rt_hw_iic_register(
device->rx_indicate = RT_NULL; device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL; device->tx_complete = RT_NULL;
device->init = rt_iic_init; device->init = rt_iic_init;
device->open = RT_NULL; device->open = rt_iic_open;
device->close = RT_NULL; device->close = rt_iic_close;
device->read = rt_iic_read; device->read = rt_iic_read;
device->write = rt_iic_write; device->write = rt_iic_write;
device->control = rt_iic_control; device->control = rt_iic_control;
...@@ -373,6 +535,83 @@ rt_err_t rt_hw_iic_register( ...@@ -373,6 +535,83 @@ rt_err_t rt_hw_iic_register(
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); 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 * @brief
* Initialize the specified IIC unit * Initialize the specified IIC unit
...@@ -388,23 +627,27 @@ rt_err_t rt_hw_iic_register( ...@@ -388,23 +627,27 @@ rt_err_t rt_hw_iic_register(
* Pin location number * Pin location number
*********************************************************************/ *********************************************************************/
static void rt_hw_iic_unit_init( static void rt_hw_iic_unit_init(
rt_device_t device,
rt_uint8_t unitNumber, rt_uint8_t unitNumber,
rt_uint8_t location) rt_uint8_t location)
{ {
I2C_TypeDef *iic; I2C_TypeDef *iic;
CMU_Clock_TypeDef iicClock; CMU_Clock_TypeDef iicClock;
I2C_Init_TypeDef init = I2C_INIT_DEFAULT; I2C_Init_TypeDef init = I2C_INIT_DEFAULT;
efm32_irq_hook_init_t hook;
switch (unitNumber) switch (unitNumber)
{ {
case 0: case 0:
iic = I2C0; iic = I2C0;
iicClock = (CMU_Clock_TypeDef)cmuClock_I2C0; iicClock = (CMU_Clock_TypeDef)cmuClock_I2C0;
hook.unit = 0;
break; break;
#if (I2C_COUNT > 1) #if (I2C_COUNT > 1)
case 1: case 1:
iic = I2C1; iic = I2C1;
iicClock = (CMU_Clock_TypeDef)cmuClock_I2C1; iicClock = (CMU_Clock_TypeDef)cmuClock_I2C1;
hook.unit = 1;
break; break;
#endif #endif
default: default:
...@@ -432,16 +675,19 @@ static void rt_hw_iic_unit_init( ...@@ -432,16 +675,19 @@ static void rt_hw_iic_unit_init(
/* Enable SDZ and SCL pins and set location */ /* Enable SDZ and SCL pins and set location */
iic->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | \ iic->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | \
(location << _I2C_ROUTE_LOCATION_SHIFT); (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 */ /* Initializing IIC */
init.enable = false; init.enable = false;
I2C_Init(iic, &init); I2C_Init(iic, &init);
/* Abort current TX data and clear TX buffers */ /* Abort current TX data and clear TX buffers */
iic->CMD = I2C_CMD_ABORT | I2C_CMD_CLEARPC | I2C_CMD_CLEARTX; 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) ...@@ -457,22 +703,25 @@ void rt_hw_iic_init(void)
struct efm32_iic_device_t *iic; struct efm32_iic_device_t *iic;
rt_uint32_t flag; rt_uint32_t flag;
flag = RT_DEVICE_FLAG_RDWR; flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
/* register iic0 */ /* register iic0 */
#ifdef RT_USING_IIC0 #ifdef RT_USING_IIC0
iic = rt_malloc(sizeof(struct efm32_iic_device_t)); iic = rt_malloc(sizeof(struct efm32_iic_device_t));
if (iic == RT_NULL) if (iic == RT_NULL)
{ {
#ifdef RT_IIC_DEBUG
rt_kprintf("no memory for IIC0 driver\n"); rt_kprintf("no memory for IIC0 driver\n");
#endif
return; return;
} }
iic->iic_device = I2C0; iic->iic_device = I2C0;
iic->is_master = true; iic->state |= IIC_STATE_MASTER;
iic->master_address = 0x0000; iic->master_address = 0x0000;
iic->slave_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); rt_hw_iic_register(&iic0_device, RT_IIC0_NAME, flag, iic);
#endif #endif
...@@ -482,15 +731,18 @@ void rt_hw_iic_init(void) ...@@ -482,15 +731,18 @@ void rt_hw_iic_init(void)
iic = rt_malloc(sizeof(struct efm32_iic_device_t)); iic = rt_malloc(sizeof(struct efm32_iic_device_t));
if (iic == RT_NULL) if (iic == RT_NULL)
{ {
#ifdef RT_IIC_DEBUG
rt_kprintf("no memory for IIC1 driver\n"); rt_kprintf("no memory for IIC1 driver\n");
#endif
return; return;
} }
iic->iic_device = I2C1; iic->iic_device = I2C1;
iic->is_master = true; iic->state |= IIC_STATE_MASTER;
iic->master_address = 0x0000; iic->master_address = 0x0000;
iic->slave_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); rt_hw_iic_register(&iic1_device, RT_IIC1_NAME, flag, iic);
#endif #endif
......
...@@ -18,23 +18,41 @@ ...@@ -18,23 +18,41 @@
/* Includes -------------------------------------------------------------------*/ /* Includes -------------------------------------------------------------------*/
/* Exported types -------------------------------------------------------------*/ /* 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 struct efm32_iic_device_t
{ {
/* State */
rt_uint8_t state;
/* Pointer to IIC device structure */
I2C_TypeDef* iic_device; I2C_TypeDef* iic_device;
rt_bool_t is_master; /* Master address */
rt_uint16_t master_address; rt_uint16_t master_address;
/* Slave address */
rt_uint16_t slave_address; rt_uint16_t slave_address;
/* RX structure */
struct efm32_iic_int_mode_t *rx_buffer;
}; };
struct efm32_iic_control_t struct efm32_iic_control_t
{ {
rt_bool_t is_master; rt_uint8_t config;
rt_uint16_t master_address; rt_uint16_t master_address;
rt_uint16_t slave_address; rt_uint16_t slave_address;
}; };
/* Exported constants ---------------------------------------------------------*/ /* Exported constants ---------------------------------------------------------*/
/* Exported macro -------------------------------------------------------------*/ /* 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 --------------------------------------------------------- */ /* Exported functions --------------------------------------------------------- */
void rt_hw_iic_init(void); void rt_hw_iic_init(void);
......
...@@ -173,8 +173,9 @@ void rt_hw_rtc_init(void) ...@@ -173,8 +173,9 @@ void rt_hw_rtc_init(void)
rt_uint32_t reset; rt_uint32_t reset;
reset = RMU_ResetCauseGet(); 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; RTC_Init_TypeDef rtcInit;
efm32_irq_hook_init_t hook; efm32_irq_hook_init_t hook;
......
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
(p * (EFM32_HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000)) (p * (EFM32_HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000))
/* Private variables ------------------------------------------------------------*/ /* Private variables ------------------------------------------------------------*/
#ifdef RT_USING_TIMER1
static struct rt_device timer1_device;
#endif
#ifdef RT_USING_TIMER2 #ifdef RT_USING_TIMER2
static struct rt_device timer2_device; static struct rt_device timer2_device;
#endif #endif
...@@ -113,15 +116,20 @@ static rt_err_t rt_hs_timer_control ( ...@@ -113,15 +116,20 @@ static rt_err_t rt_hs_timer_control (
{ {
/* change device setting */ /* change device setting */
struct efm32_timer_control_t *control; struct efm32_timer_control_t *control;
rt_uint32_t running;
control = (struct efm32_timer_control_t *)args; control = (struct efm32_timer_control_t *)args;
running = timer->timer_device->STATUS & 0x00000001;
TIMER_Enable(timer->timer_device, false); TIMER_Enable(timer->timer_device, false);
timer->timer_device->CNT = _TIMER_CNT_RESETVALUE; timer->timer_device->CNT = _TIMER_CNT_RESETVALUE;
TIMER_TopSet(timer->timer_device, TIMER_TopCalculate(control->period)); TIMER_TopSet(timer->timer_device, TIMER_TopCalculate(control->period));
timer->hook.cbFunc = control->hook.cbFunc; timer->hook.cbFunc = control->hook.cbFunc;
timer->hook.userPtr = control->hook.userPtr; timer->hook.userPtr = control->hook.userPtr;
TIMER_Enable(timer->timer_device, true); if (running)
{
TIMER_Enable(timer->timer_device, true);
}
} }
break; break;
} }
...@@ -224,16 +232,67 @@ void rt_hw_timer_init(void) ...@@ -224,16 +232,67 @@ void rt_hw_timer_init(void)
init.oneShot = false; init.oneShot = false;
init.sync = 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 #ifdef RT_USING_TIMER2
timer = rt_malloc(sizeof(struct efm32_timer_device_t)); timer = rt_malloc(sizeof(struct efm32_timer_device_t));
if (timer == RT_NULL) 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; return;
} }
timer->timer_device = TIMER2; 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 */ /* Enable clock for TIMERn module */
CMU_ClockEnable(cmuClock_TIMER2, true); CMU_ClockEnable(cmuClock_TIMER2, true);
......
...@@ -140,7 +140,9 @@ static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag) ...@@ -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) 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"); rt_kprintf("no memory for serial RX buffer\n");
#endif
return -RT_ENOMEM; return -RT_ENOMEM;
} }
rt_memset(int_mode->data_ptr, 0, SERIAL_RX_BUFFER_SIZE); rt_memset(int_mode->data_ptr, 0, SERIAL_RX_BUFFER_SIZE);
...@@ -498,10 +500,13 @@ static rt_err_t rt_usart_control ( ...@@ -498,10 +500,13 @@ static rt_err_t rt_usart_control (
if ((int_rx->data_ptr = rt_realloc(int_rx->data_ptr, size)) \ if ((int_rx->data_ptr = rt_realloc(int_rx->data_ptr, size)) \
== RT_NULL) == RT_NULL)
{ {
#ifdef RT_USART_DEBUG
rt_kprintf("no memory for usart rx buffer\n"); rt_kprintf("no memory for usart rx buffer\n");
#endif
return -RT_ENOMEM; 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 else
...@@ -509,7 +514,9 @@ static rt_err_t rt_usart_control ( ...@@ -509,7 +514,9 @@ static rt_err_t rt_usart_control (
/* Allocate new RX buffer */ /* Allocate new RX buffer */
if ((int_rx->data_ptr = rt_malloc(size)) == RT_NULL) if ((int_rx->data_ptr = rt_malloc(size)) == RT_NULL)
{ {
#ifdef RT_USART_DEBUG
rt_kprintf("no memory for usart rx buffer\n"); rt_kprintf("no memory for usart rx buffer\n");
#endif
return -RT_ENOMEM; return -RT_ENOMEM;
} }
} }
...@@ -726,7 +733,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init( ...@@ -726,7 +733,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
usart = rt_malloc(sizeof(struct efm32_usart_device_t)); usart = rt_malloc(sizeof(struct efm32_usart_device_t));
if (usart == RT_NULL) if (usart == RT_NULL)
{ {
#ifdef RT_USART_DEBUG
rt_kprintf("no memory for USART driver\n"); rt_kprintf("no memory for USART driver\n");
#endif
return usart; return usart;
} }
usart->unit = unitNumber; usart->unit = unitNumber;
...@@ -748,7 +757,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init( ...@@ -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)); usart->tx_mode = dma_mode = rt_malloc(sizeof(struct efm32_usart_dma_mode_t));
if (dma_mode == RT_NULL) if (dma_mode == RT_NULL)
{ {
#ifdef RT_USART_DEBUG
rt_kprintf("no memory for USART TX by DMA\n"); rt_kprintf("no memory for USART TX by DMA\n");
#endif
rt_free(usart->rx_mode); rt_free(usart->rx_mode);
rt_free(usart); rt_free(usart);
usart = RT_NULL; usart = RT_NULL;
...@@ -763,7 +774,9 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init( ...@@ -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)); usart->rx_mode = rt_malloc(sizeof(struct efm32_usart_int_mode_t));
if (usart->rx_mode == RT_NULL) if (usart->rx_mode == RT_NULL)
{ {
#ifdef RT_USART_DEBUG
rt_kprintf("no memory for USART RX by interrupt\n"); rt_kprintf("no memory for USART RX by interrupt\n");
#endif
rt_free(usart->tx_mode); rt_free(usart->tx_mode);
rt_free(usart); rt_free(usart);
usart = RT_NULL; usart = RT_NULL;
......
...@@ -39,16 +39,12 @@ struct efm32_usart_device_t ...@@ -39,16 +39,12 @@ struct efm32_usart_device_t
{ {
/* Unit number */ /* Unit number */
rt_uint8_t unit; rt_uint8_t unit;
/* State */ /* State */
rt_uint32_t state; rt_uint8_t state;
/* Pointer to USART device structure */ /* Pointer to USART device structure */
USART_TypeDef* usart_device; USART_TypeDef* usart_device;
/* Pointer to RX structure */ /* Pointer to RX structure */
void *rx_mode; void *rx_mode;
/* Pointer to TX structure */ /* Pointer to TX structure */
void *tx_mode; void *tx_mode;
}; };
......
...@@ -33,6 +33,7 @@ efm32_irq_hook_t rtcCbTable[RTC_COUNT] = {RT_NULL}; ...@@ -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 gpioCbTable[16] = {RT_NULL};
efm32_irq_hook_t acmpCbTable[ACMP_COUNT] = {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 usartCbTable[USART_COUNT * 2] = {RT_NULL};
efm32_irq_hook_t iicCbTable[I2C_COUNT] = {RT_NULL};
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/
...@@ -181,6 +182,31 @@ void DMA_IRQHandler_All(unsigned int channel, bool primary, void *user) ...@@ -181,6 +182,31 @@ void DMA_IRQHandler_All(unsigned int channel, bool primary, void *user)
rt_interrupt_leave(); 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 * @brief
* Common Timer2 interrupt handler * Common Timer2 interrupt handler
...@@ -502,6 +528,32 @@ void USART2_RX_IRQHandler(void) ...@@ -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 * @brief
* EFM32 common interrupt handlers register function * EFM32 common interrupt handlers register function
...@@ -545,6 +597,11 @@ rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook) ...@@ -545,6 +597,11 @@ rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
usartCbTable[hook->unit].userPtr = hook->userPtr; usartCbTable[hook->unit].userPtr = hook->userPtr;
break; break;
case efm32_irq_type_iic:
iicCbTable[hook->unit].cbFunc = hook->cbFunc;
iicCbTable[hook->unit].userPtr = hook->userPtr;
break;
default: default:
break; break;
} }
......
...@@ -25,7 +25,8 @@ enum efm32_irq_hook_type_t ...@@ -25,7 +25,8 @@ enum efm32_irq_hook_type_t
efm32_irq_type_timer, efm32_irq_type_timer,
efm32_irq_type_gpio, efm32_irq_type_gpio,
efm32_irq_type_acmp, 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); typedef void (*efm32_irq_callback_t)(rt_device_t device);
......
...@@ -33,13 +33,16 @@ ...@@ -33,13 +33,16 @@
#define RT_MEM_DEBUG #define RT_MEM_DEBUG
//#define THREAD_DEBUG //#define THREAD_DEBUG
//#define IRQ_DEBUG //#define IRQ_DEBUG
#define RT_USING_OVERFLOW_CHECK
//#define RT_IRQHDL_DEBUG //#define RT_IRQHDL_DEBUG
//#define RT_ADC_DEBUG //#define RT_ADC_DEBUG
#define RT_USING_OVERFLOW_CHECK //#define RT_ACMP_DEBUG
#define RT_USART_DEBUG //#define RT_TIMER_DEBUG
//#define RT_USART_DEBUG
/* Using Hook */ /* Using Hook */
#define RT_USING_HOOK //#define RT_USING_HOOK
/* Using Software Timer */ /* Using Software Timer */
/* #define RT_USING_TIMER_SOFT */ /* #define RT_USING_TIMER_SOFT */
...@@ -52,20 +55,20 @@ ...@@ -52,20 +55,20 @@
#define RT_USING_SEMAPHORE #define RT_USING_SEMAPHORE
/* Using Mutex */ /* Using Mutex */
#define RT_USING_MUTEX //#define RT_USING_MUTEX
/* Using Event */ /* Using Event */
#define RT_USING_EVENT //#define RT_USING_EVENT
/* Using MailBox */ /* Using MailBox */
#define RT_USING_MAILBOX //#define RT_USING_MAILBOX
/* Using Message Queue */ /* Using Message Queue */
#define RT_USING_MESSAGEQUEUE //#define RT_USING_MESSAGEQUEUE
/* SECTION: Memory Management */ /* SECTION: Memory Management */
/* Using Memory Pool Management*/ /* Using Memory Pool Management*/
#define RT_USING_MEMPOOL //#define RT_USING_MEMPOOL
/* Using Dynamic Heap Management */ /* Using Dynamic Heap Management */
#define RT_USING_HEAP #define RT_USING_HEAP
...@@ -110,6 +113,7 @@ ...@@ -110,6 +113,7 @@
#endif #endif
/* SECTION: Console options */ /* SECTION: Console options */
#define RT_USING_CONSOLE
/* the buffer size of console*/ /* the buffer size of console*/
#define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLEBUF_SIZE 128
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册