*** 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:
parent
2e59147522
commit
578b245b0e
|
@ -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 */ \
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue