Beispiel #1
0
rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
                            const void *data_ptr,
                            rt_size_t data_size,
                            rt_int32_t timeout)
{
    rt_uint16_t mask;
    rt_ubase_t  level;
    rt_thread_t thread;
    rt_err_t    result;
    
    RT_ASSERT(queue != RT_NULL);

    result = RT_EOK;
    thread = rt_thread_self();
    mask = queue->size - 1;

    level = rt_hw_interrupt_disable();
    while (queue->put_index - queue->get_index == queue->size)
    {
        queue->waiting_lwm = RT_TRUE;

        /* queue is full */
        if (timeout == 0)
        {
            result = -RT_ETIMEOUT;

            goto __exit;
        }

        /* current context checking */
        RT_DEBUG_NOT_IN_INTERRUPT;

        /* reset thread error number */
        thread->error = RT_EOK;
        
        /* suspend thread on the push list */
        rt_thread_suspend(thread);
        rt_list_insert_before(&(queue->suspended_push_list), &(thread->tlist));
        /* start timer */
        if (timeout > 0)
        {
            /* reset the timeout of thread timer and start it */
            rt_timer_control(&(thread->thread_timer),
                             RT_TIMER_CTRL_SET_TIME,
                             &timeout);
            rt_timer_start(&(thread->thread_timer));
        }

        /* enable interrupt */
        rt_hw_interrupt_enable(level);

        /* do schedule */
        rt_schedule();

        /* thread is waked up */
        result = thread->error;
        level = rt_hw_interrupt_disable();
        if (result != RT_EOK) goto __exit;
    }

    queue->queue[queue->put_index & mask].data_ptr  = data_ptr;
    queue->queue[queue->put_index & mask].data_size = data_size;
    queue->put_index += 1;

    if (!rt_list_isempty(&(queue->suspended_pop_list)))
    {
        /* there is at least one thread in suspended list */

        /* get thread entry */
        thread = rt_list_entry(queue->suspended_pop_list.next,
                               struct rt_thread,
                               tlist);

        /* resume it */
        rt_thread_resume(thread);
        rt_hw_interrupt_enable(level);

        /* perform a schedule */
        rt_schedule();

        return result;
    }
/**
 * This function will allocate a block from memory pool
 *
 * @param mp the memory pool object
 * @param time the waiting time
 *
 * @return the allocated memory block or RT_NULL on allocated failed
 */
void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time)
{
	rt_uint8_t *block_ptr;
	register rt_base_t level;
	struct rt_thread *thread;

	/* disable interrupt */
	level = rt_hw_interrupt_disable();

	if (mp->block_free_count)
	{
		/* memory block is available. decrease the free block counter */
		mp->block_free_count --;

		/* get block from block list */
		block_ptr = mp->block_list;
		mp->block_list = *(rt_uint8_t **)block_ptr;

		/* point to memory pool */
		*(rt_uint8_t **)block_ptr = (rt_uint8_t *)mp;
	}
	else
	{
		/* memory block is unavailable. */
		if (time == 0)
		{
			/* enable interrupt */
			rt_hw_interrupt_enable(level);
			return RT_NULL;
		}
		else
		{
			RT_DEBUG_NOT_IN_INTERRUPT;

			/* get current thread */
			thread = rt_thread_self();

			/* need suspend thread */
			rt_thread_suspend(thread);
			rt_list_insert_after(&(mp->suspend_thread), &(thread->tlist));
			mp->suspend_thread_count ++;

			if (time > 0)
			{
				/* init thread timer and start it */
				rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
				rt_timer_start(&(thread->thread_timer));
			}

			/* enable interrupt */
			rt_hw_interrupt_enable(level);

			/* do a schedule */
			rt_schedule();

			if (thread->error != RT_EOK)
				return RT_NULL;

			/* disable interrupt */
			level = rt_hw_interrupt_disable();

			/* decrease free block */
			mp->block_free_count --;

			/* get block from block list */
			block_ptr = mp->block_list;
			mp->block_list = *(rt_uint8_t **)block_ptr;

			/* point to memory pool */
			*(rt_uint8_t **)block_ptr = (rt_uint8_t *)mp;
		}
	}

	/* enable interrupt */
	rt_hw_interrupt_enable(level);

	RT_OBJECT_HOOK_CALL(rt_mp_alloc_hook, (mp, (rt_uint8_t *)(block_ptr + sizeof(rt_uint8_t *))));

	return (rt_uint8_t *)(block_ptr + sizeof(rt_uint8_t *));
}
Beispiel #3
0
/* FIXME(Heyong): add for print the system infos when sys abort */
static void _rtt_statistics()
{
    rt_uint32_t total;
    rt_uint32_t used;
    rt_uint32_t max_used;
    struct rt_thread *thread;
    struct rt_list_node *node;
    rt_uint8_t *ptr;

    rt_base_t level;
    struct rt_object_information *information;

    information = rt_object_get_information(RT_Object_Class_Thread);
    RT_ASSERT(information != RT_NULL);

    struct rt_list_node *list = &(information->object_list);

    level = rt_hw_interrupt_disable();

    for (node = list->next; node != list; node = node->next)
    {
        thread = rt_list_entry(node, struct rt_thread, list);
        //if(thread) thread->total_tick = 0;
    }

    rt_hw_interrupt_enable(level);
    rt_memory_info(&total,&used,&max_used);
    rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
    rt_kprintf("\n         memory info       size \n");
    rt_kprintf("------------------------- ------\n");
    rt_kprintf("total memory:             (%dKB)\n",  total/1024);
    rt_kprintf("used memory :             (%dKB)\n",  used/1024);
    rt_kprintf("maximum allocated memory: (%dKB)\n\n",  max_used/1024);

    rt_kprintf("          thread                 pri  status     sp     stack addr stack size  max used \n");
    rt_kprintf("-------------------------------- --- ------- ---------- ---------- ---------- ---------- \n");
    for (node = list->next; node != list; node = node->next)
    {
        thread = rt_list_entry(node, struct rt_thread, list);
#if 0
        rt_kprintf("%-32.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
#else
        int priority = thread->current_priority;
        rt_kprintf("%-32.*s %03d", RT_NAME_MAX, thread->name, priority);
#endif
        if (thread->stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
        else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
        else if (thread->stat == RT_THREAD_INIT)    rt_kprintf(" init   ");
        else if (thread->stat == RT_THREAD_CLOSE)   rt_kprintf(" close  ");

        ptr = (rt_uint8_t*)thread->stack_addr;
        while (*ptr == '#')ptr++;

        rt_kprintf("  0x%08x 0x%08x 0x%08x 0x%08x  \n",
            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
            thread->stack_addr,
            thread->stack_size,
            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr)
           );
    }
    rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
}
Beispiel #4
0
/**
 * This function will release a mutex, if there are threads suspended on mutex,
 * it will be waked up.
 *
 * @param mutex the mutex object
 *
 * @return the error code
 */
rt_err_t rt_mutex_release(rt_mutex_t mutex)
{
	register rt_base_t temp;
	struct rt_thread *thread;
	rt_bool_t need_schedule;

	need_schedule = RT_FALSE;

	/* get current thread */
	thread = rt_thread_self();

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

	RT_DEBUG_LOG(RT_DEBUG_IPC,
		("mutex_release:current thread %s, mutex value: %d, hold: %d\n",
		thread->name, mutex->value, mutex->hold));

	RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mutex->parent.parent)));

	/* mutex only can be released by owner */
	if (thread != mutex->owner)
	{
		thread->error = -RT_ERROR;

		/* enable interrupt */
		rt_hw_interrupt_enable(temp);

		return -RT_ERROR;
	}

	/* decrease hold */
	mutex->hold --;
	/* if no hold */
	if (mutex->hold == 0)
	{
		/* change the owner thread to original priority */
		if (mutex->original_priority != mutex->owner->current_priority)
		{
			rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY,
				&(mutex->original_priority));
		}

		/* wakeup suspended thread */
		if (!rt_list_isempty(&mutex->parent.suspend_thread))
		{
			/* get suspended thread */
			thread = rt_list_entry(mutex->parent.suspend_thread.next, struct rt_thread, tlist);

			RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_release: resume thread: %s\n", thread->name));

			/* set new owner and priority */
			mutex->owner = thread;
			mutex->original_priority = thread->current_priority;
			mutex->hold ++;

			/* resume thread */
			rt_ipc_list_resume(&(mutex->parent.suspend_thread));

			need_schedule = RT_TRUE;
		}
		else
		{
Beispiel #5
0
/***************************************************************************//**
 * @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;
    }
}
Beispiel #6
0
static rt_size_t rt_serial_write(struct rt_device *dev,
                                 rt_off_t          pos,
                                 const void       *buffer,
                                 rt_size_t         size)
{
    rt_uint8_t *ptr;
    rt_size_t write_nbytes = 0;
    struct rt_serial_device *serial;

    RT_ASSERT(dev != RT_NULL);
    serial = (struct rt_serial_device *)dev;

    ptr = (rt_uint8_t*)buffer;

    if (dev->flag & RT_DEVICE_FLAG_INT_TX)
    {
        /* warning: data will be discarded if buffer is full */
        while (size)
        {
            if (serial_ringbuffer_putchar(serial->int_tx, *ptr) != -1)
            {
                ptr ++;
                size --;
            }
            else
                break;
        }
    }
    else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
    {
        const void *data_ptr = RT_NULL;
        rt_size_t data_size = 0;
        rt_base_t level;
        rt_err_t result;
        
        RT_ASSERT(0 == (dev->flag & RT_DEVICE_FLAG_STREAM));

        result = rt_data_queue_push(&(serial->tx_dq), buffer, size, 20); 
        if (result == RT_EOK)
        {
            level = rt_hw_interrupt_disable();
            if (serial->dma_flag == RT_FALSE)
            {
                serial->dma_flag = RT_TRUE;
                rt_hw_interrupt_enable(level);
            
                if (RT_EOK == rt_data_queue_pop(&(serial->tx_dq), &data_ptr, &data_size, 0))
                {
                    serial->ops->dma_transmit(serial, data_ptr, data_size);
                }
            }
            else
                rt_hw_interrupt_enable(level);

            return size;
        }
        else
        {
            rt_set_errno(result);

            return 0;
        }
    }
    else
    {
        /* polling mode */
        while (size)
        {
            /*
             * to be polite with serial console add a line feed
             * to the carriage return character
             */
            if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
            {
                serial->ops->putc(serial, '\r');
            }

            serial->ops->putc(serial, *ptr);

            ++ ptr;
            -- size;
        }
    }

    write_nbytes = (rt_uint32_t)ptr - (rt_uint32_t)buffer;
    if (write_nbytes == 0)
    {
        rt_set_errno(-RT_EFULL);
    }

    return write_nbytes;
}
Beispiel #7
0
/**
 * This function will take a semaphore, if the semaphore is unavailable, the
 * thread shall wait for a specified time.
 *
 * @param sem the semaphore object
 * @param time the waiting time
 *
 * @return the error code
 */
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)
{
	register rt_base_t temp;
	struct rt_thread *thread;

	RT_ASSERT(sem != RT_NULL);

	RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(sem->parent.parent)));

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

	RT_DEBUG_LOG(RT_DEBUG_IPC,
		("thread %s take sem:%s, which value is: %d\n", rt_thread_self()->name,
		((struct rt_object *)sem)->name, sem->value));

	if (sem->value > 0)
	{
		/* semaphore is available */
		sem->value --;

		/* enable interrupt */
		rt_hw_interrupt_enable(temp);
	}
	else
	{
		/* no waiting, return with timeout */
		if (time == 0)
		{
			rt_hw_interrupt_enable(temp);
			return -RT_ETIMEOUT;
		}
		else
		{
			/* current context checking */
			RT_DEBUG_NOT_IN_INTERRUPT;

			/* semaphore is unavailable, push to suspend list */
			/* get current thread */
			thread = rt_thread_self();

			/* reset thread error number */
			thread->error = RT_EOK;

			RT_DEBUG_LOG(RT_DEBUG_IPC, ("sem take: suspend thread - %s\n", thread->name));

			/* suspend thread */
			rt_ipc_list_suspend(&(sem->parent.suspend_thread),
				thread, sem->parent.parent.flag);

			/* has waiting time, start thread timer */
			if (time > 0)
			{
				RT_DEBUG_LOG(RT_DEBUG_IPC, ("set thread:%s to timer list\n", thread->name));

				/* reset the timeout of thread timer and start it */
				rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
				rt_timer_start(&(thread->thread_timer));
			}

			/* enable interrupt */
			rt_hw_interrupt_enable(temp);

			/* do schedule */
			rt_schedule();

			if (thread->error != RT_EOK)
			{
				return thread->error;
			}
		}
	}

	RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(sem->parent.parent)));

	return RT_EOK;
}
Beispiel #8
0
rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
                              rt_uint32_t enabled)
{
    const struct pin_index *index;
    const struct pin_irq_map *irqmap;
    rt_base_t level;
    rt_int32_t irqindex = -1;
    GPIO_InitTypeDef GPIO_InitStruct;

    index = get_pin(pin);
    if (index == RT_NULL)
    {
        return RT_ENOSYS;
    }
    if (enabled == PIN_IRQ_ENABLE)
    {
        irqindex = bit2bitno(index->pin);
        if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
        {
            return RT_ENOSYS;
        }
        level = rt_hw_interrupt_disable();
        if (pin_irq_hdr_tab[irqindex].pin == -1)
        {
            rt_hw_interrupt_enable(level);
            return RT_ENOSYS;
        }
        irqmap = &pin_irq_map[irqindex];
        /* GPIO Periph clock enable */
        index->rcc();
        /* Configure GPIO_InitStructure */
        GPIO_InitStruct.Pin = index->pin;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        switch (pin_irq_hdr_tab[irqindex].mode)
        {
        case PIN_IRQ_MODE_RISING:
            GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
            break;
        case PIN_IRQ_MODE_FALLING:
            GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
            break;
        case PIN_IRQ_MODE_RISING_FALLING:
            GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
            break;
        }
        HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
        HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);
        HAL_NVIC_EnableIRQ(irqmap->irqno);
        rt_hw_interrupt_enable(level);
    }
    else if (enabled == PIN_IRQ_DISABLE)
    {
        irqmap = get_pin_irq_map(index->pin);
        if (irqmap == RT_NULL)
        {
            return RT_ENOSYS;
        }
        HAL_NVIC_DisableIRQ(irqmap->irqno);
    }
    else
    {
        return RT_ENOSYS;
    }

    return RT_EOK;
}
Beispiel #9
0
/**
 * This function will start the timer
 *
 * @param timer the timer to be started
 *
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
 */
rt_err_t rt_timer_start(rt_timer_t timer)
{
    int row_lvl;
    rt_list_t *timer_list;
    register rt_base_t level;
    rt_list_t *row_head[RT_TIMER_SKIP_LIST_LEVEL];
    unsigned int tst_nr;
    static unsigned int random_nr;

    /* timer check */
    RT_ASSERT(timer != RT_NULL);
    if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
        return -RT_ERROR;

    RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));

    /*
     * get timeout tick,
     * the max timeout tick shall not great than RT_TICK_MAX/2
     */
    RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2);
    timer->timeout_tick = rt_tick_get() + timer->init_tick;

    /* disable interrupt */
    level = rt_hw_interrupt_disable();

#ifdef RT_USING_TIMER_SOFT
    if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
    {
        /* insert timer to soft timer list */
        timer_list = rt_soft_timer_list;
    }
    else
#endif
    {
        /* insert timer to system timer list */
        timer_list = rt_timer_list;
    }

    row_head[0]  = &timer_list[0];
    for (row_lvl = 0; row_lvl < RT_TIMER_SKIP_LIST_LEVEL; row_lvl++)
    {
        for (;row_head[row_lvl] != timer_list[row_lvl].prev;
             row_head[row_lvl]  = row_head[row_lvl]->next)
        {
            struct rt_timer *t;
            rt_list_t *p = row_head[row_lvl]->next;

            /* fix up the entry pointer */
            t = rt_list_entry(p, struct rt_timer, row[row_lvl]);

            /* If we have two timers that timeout at the same time, it's
             * preferred that the timer inserted early get called early.
             * So insert the new timer to the end the the some-timeout timer
             * list.
             */
            if ((t->timeout_tick - timer->timeout_tick) == 0)
            {
                continue;
            }
            else if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX / 2)
            {
                break;
            }
        }
        if (row_lvl != RT_TIMER_SKIP_LIST_LEVEL - 1)
            row_head[row_lvl+1] = row_head[row_lvl]+1;
    }

    /* Interestingly, this super simple timer insert counter works very very
     * well on distributing the list height uniformly. By means of "very very
     * well", I mean it beats the randomness of timer->timeout_tick very easily
     * (actually, the timeout_tick is not random and easy to be attacked). */
    random_nr++;
    tst_nr = random_nr;

    rt_list_insert_after(row_head[RT_TIMER_SKIP_LIST_LEVEL-1],
                         &(timer->row[RT_TIMER_SKIP_LIST_LEVEL-1]));
    for (row_lvl = 2; row_lvl <= RT_TIMER_SKIP_LIST_LEVEL; row_lvl++)
    {
        if (!(tst_nr & RT_TIMER_SKIP_LIST_MASK))
            rt_list_insert_after(row_head[RT_TIMER_SKIP_LIST_LEVEL - row_lvl],
                                 &(timer->row[RT_TIMER_SKIP_LIST_LEVEL - row_lvl]));
        else
            break;
        /* Shift over the bits we have tested. Works well with 1 bit and 2
         * bits. */
        tst_nr >>= (RT_TIMER_SKIP_LIST_MASK+1)>>1;
    }

    timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;

    /* enable interrupt */
    rt_hw_interrupt_enable(level);

#ifdef RT_USING_TIMER_SOFT
    if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
    {
        /* check whether timer thread is ready */
        if (timer_thread.stat != RT_THREAD_READY)
        {
            /* resume timer thread to check soft timer */
            rt_thread_resume(&timer_thread);
            rt_schedule();
        }
    }
#endif

    return -RT_EOK;
}
Beispiel #10
0
void usart_rx_thread_entry(void *p)
{
	unsigned short max_interval,max_datalen;
	unsigned int current_mode;

	getFrameSplit(&max_interval,&max_datalen);
    current_mode = getWorkingMode();

    while( rt_sem_take(&rx_sem,RT_WAITING_FOREVER) == RT_EOK )
    {
        register rt_base_t temp;
        FEED_THE_DOG();

        // if rj45 not connected, we should route data between 232 and 485.
        if( getLinkStatus() == 0 )
        {
            // we split rx_buf to 2 parts in order to save space.
            int len1,len2;
            // Clear the semaphore.
            temp = rt_hw_interrupt_disable();
            rx_sem.value = 0;
            rt_hw_interrupt_enable(temp);
            do
            {
                usart_led_flash();

                // recv usart1
                rt_sem_take(&tx2_sem,RT_WAITING_FOREVER);
                len1 = rt_device_read(dev_uart1,0,rx_buf,RX_BUF_SIZE/2);
                if( len1 )
                    dev_uart2->write(dev_uart2, 0, rx_buf, len1);
                else
                    rt_sem_release(&tx2_sem);

                // recv usart2
                rt_sem_take(&tx1_sem,RT_WAITING_FOREVER);
                len2 = rt_device_read(dev_uart2,0,rx_buf+RX_BUF_SIZE/2,RX_BUF_SIZE/2);
                if( len2 )
                    dev_uart1->write(dev_uart1, 0, rx_buf+RX_BUF_SIZE/2, len2);
                else
                    rt_sem_release(&tx1_sem);
            }while( (len1 != 0) && (len2 != 0) );
            continue;
        }
        else
        {
            // Clear the semaphore.
            temp = rt_hw_interrupt_disable();
            rx_sem.value = 0;
            rt_hw_interrupt_enable(temp);
            while( 1 )
            {
                int len;

                usart_led_flash();

                // read data.
                len = rt_device_read(dev_uart1,0,rx_buf+rx_buf_offset,RX_BUF_SIZE-rx_buf_offset);
                if( len == 0 )
                {
                    len = rt_device_read(dev_uart2,0,rx_buf+rx_buf_offset,RX_BUF_SIZE-rx_buf_offset);
                }
                usart_bytes_recv += len;

                // If buffer is empty and we received data, start the timer.
                if( rx_buf_offset == 0 )
                {
                    if( len == 0 )
                    {
                        break;
                    }
                    else
                    {
                        // if interval less than 10ms, we send data immediately.
                        if( max_interval >= 10 )
                            rt_timer_start(&max_interval_timer);
                    }
                }

                // move offset pointer.
                rx_buf_offset += len;

                // check if we should send data out.
                if( rx_buf_offset < max_datalen &&
                    max_interval_timer.parent.flag & RT_TIMER_FLAG_ACTIVATED )
                {
                    break;
                }

                // Send data out.
                if((current_mode == TCP_SERVER)||
                        (current_mode == TCP_CLIENT)||
                        (current_mode == TCP_AUTO))
                {
                    int i;
                    // send data.
                    for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ )
                    {
                        // we should not use RT_WAITING_FOREVER here.
                        if( rt_mutex_take(&(socket_list[i].mu_sock),10) != RT_EOK )
                            continue;
                        // slot not used.
                        if( socket_list[i].used )
                        {
                            // shall not blocking.
                            if( lwip_send(socket_list[i].socket,rx_buf,rx_buf_offset,0) < 0 )
                            {
                                // connection lost.
                                lwip_close(socket_list[i].socket);
                                socket_list[i].used = 0;
                                rt_kprintf("Connection lost.\n");
                            }
                        }
                        rt_mutex_release(&(socket_list[i].mu_sock));
                    }
                }
                else if( (current_mode == UDP)||
                        (current_mode == UDP_MULTICAST) )
                {
                    if( rt_mutex_take(&(socket_list[0].mu_sock),10) == RT_EOK )
                    {
                        if( socket_list[0].used )
                        {
                            lwip_sendto(socket_list[0].socket,rx_buf,rx_buf_offset,0,
                                    (struct sockaddr*)&(socket_list[0].cliaddr), sizeof(struct sockaddr));
                        }
                        rt_mutex_release(&(socket_list[0].mu_sock));
                    }
                }
                else
                {
                    rt_kprintf("fatal error! rx thread exits.\n");
                    return;
                }
                rx_buf_offset = 0;
            }
        }
    }
    rt_kprintf("Error taking semaphore, usart rx exit!\n");
}
Beispiel #11
0
static void rt_console_isr(int vector, void* param)
{
    char c;
	rt_bool_t ret;
    rt_base_t level;

	if(INTUART0_RX == vector)
	{
		c = rt_serial_getc();
		ret = RT_TRUE;
	}
	else
	{
		rt_keyboard_isr();

		ret = rt_keyboard_getc(&c);
	}

	if(ret == RT_FALSE)
	{
		/* do nothing */
	}
	else
	{
		/* disable interrupt */
		level = rt_hw_interrupt_disable();

		/* save character */
		rx_buffer[save_index] = c;
		save_index ++;
		if (save_index >= CONSOLE_RX_BUFFER_SIZE)
			save_index = 0;

		/* if the next position is read index, discard this 'read char' */
		if (save_index == read_index)
		{
			read_index ++;
			if (read_index >= CONSOLE_RX_BUFFER_SIZE)
				read_index = 0;
		}

		/* enable interrupt */
		rt_hw_interrupt_enable(level);
	}

    /* invoke callback */
    if (console_device.rx_indicate != RT_NULL)
    {
        rt_size_t rx_length;

        /* get rx length */
        rx_length = read_index > save_index ?
			CONSOLE_RX_BUFFER_SIZE - read_index + save_index :
			save_index - read_index;

        if(rx_length > 0)
        {
            console_device.rx_indicate(&console_device, rx_length);
        }
    }
    else
    {

    }
}
Beispiel #12
0
/**
 *  @brief This function processes received packet and forwards it
 *  to kernel/upper layer
 *  
 *  @param priv    A pointer to wlan_private
 *  @param skb     A pointer to skb which includes the received packet
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
void ProcessRxedPacket(WlanCard *cardinfo,u8 *data,u32 len)
{
	struct pbuf* p = RT_NULL;
	RxPacketHdr_t *pRxPkt;
	RxPD *pRxPD;
	u32 pbuflen;
	int hdrChop;
	int minlen;
	EthII_Hdr_t *pEthHdr;
	Rx_Pbuf_List *RxNode = NULL;
	rt_base_t level;
	WlanCard *card = cardinfo;
	Rx_Pbuf_List *HeadNode = &card->RxList;
	const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };

	RxNode = rt_malloc(sizeof(RxNode));
	if (RxNode == NULL)
	{
		WlanDebug(WlanErr,"RX packet Error: memory alloc failed\r\n");
		goto done;
	}

	pRxPD = (RxPD *) data;
	pRxPkt = (RxPacketHdr_t *) ((u8 *) pRxPD + pRxPD->PktOffset);
	/*mac source address :6byte  .mac destination address :6byte. length 2 bytes =14*/
	minlen = (8 + 4 + (pRxPD->PktOffset));
	if (len < minlen)
	{
		WlanDebug( WlanErr,"RX Error: packet length is too long\n");
		rt_free(RxNode);
		goto done;
	}

	WlanDebug(WlanData, "RX Data:%d\n",len - pRxPD->PktOffset);
	WlanDebug(WlanData, "SNR: %d, NF: %d\n", pRxPD->SNR, pRxPD->NF);
	WlanDebug(WlanData,"RX Data Dest \r\n %x,%x,%x,%x,%x,%x\r\n", pRxPkt->eth803_hdr.dest_addr[0],
			pRxPkt->eth803_hdr.dest_addr[1],
			pRxPkt->eth803_hdr.dest_addr[2],
			pRxPkt->eth803_hdr.dest_addr[3],
			pRxPkt->eth803_hdr.dest_addr[4],
			pRxPkt->eth803_hdr.dest_addr[5]);
	WlanDebug(WlanData,"RX Data Src\r\n %x,%x,%x,%x,%x,%x\r\n", pRxPkt->eth803_hdr.src_addr[0],
			pRxPkt->eth803_hdr.src_addr[1],
			pRxPkt->eth803_hdr.src_addr[2],
			pRxPkt->eth803_hdr.src_addr[3],
			pRxPkt->eth803_hdr.src_addr[4],
			pRxPkt->eth803_hdr.src_addr[5]);

	if (rt_memcmp(&pRxPkt->rfc1042_hdr, rfc1042_eth_hdr,
			sizeof(rfc1042_eth_hdr)) == 0)
	{
		/*
		 *  Replace the 803 header and rfc1042 header (llc/snap) with an
		 *    EthernetII header, keep the src/dst and snap_type (ethertype)
		 *
		 *  The firmware only passes up SNAP frames converting
		 *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
		 *
		 *  To create the Ethernet II, just move the src, dst address right
		 *    before the snap_type.
		 */
		pEthHdr = (EthII_Hdr_t *) ((u8 *) &pRxPkt->eth803_hdr
				+ sizeof(pRxPkt->eth803_hdr) + sizeof(pRxPkt->rfc1042_hdr)
				- sizeof(pRxPkt->eth803_hdr.dest_addr)
				- sizeof(pRxPkt->eth803_hdr.src_addr)
				- sizeof(pRxPkt->rfc1042_hdr.snap_type));

		rt_memcpy(pEthHdr->src_addr, pRxPkt->eth803_hdr.src_addr,
				sizeof(pEthHdr->src_addr));
		rt_memcpy(pEthHdr->dest_addr, pRxPkt->eth803_hdr.dest_addr,
				sizeof(pEthHdr->dest_addr));

		/* Chop off the RxPD + the excess memory from the 802.2/llc/snap header
		 *   that was removed
		 */
		hdrChop = (u8 *) pEthHdr - (u8 *) pRxPD;
	}
	else
	{
		hexdump("RX Data: LLC/SNAP", (u8 *) &pRxPkt->rfc1042_hdr,
				sizeof(pRxPkt->rfc1042_hdr));

		/* Chop off the RxPD */
		hdrChop = (u8 *) &pRxPkt->eth803_hdr - (u8 *) pRxPD;
		rt_free(RxNode);
	}

	/* Chop off the leading header bytes so the skb points to the start of
	 *   either the reconstructed EthII frame or the 802.2/llc/snap frame
	 */

	pbuflen = (len - hdrChop);
	if (pbuflen < 100)
		pbuflen = 100;
	p = pbuf_alloc(PBUF_LINK, pbuflen, PBUF_RAM);
	if (p == RT_NULL)
	{
		WlanDebug(WlanErr,"alloc pbuf failed length %d",pbuflen);
		rt_free(RxNode);
		return;
	}
	rt_memcpy(p->payload, (u8*) ((u32) pRxPD + hdrChop), pbuflen);
	RxNode->p = p;

	level = rt_hw_interrupt_disable();
	if (HeadNode->next == HeadNode)
	{
		HeadNode->next = RxNode;
		HeadNode->pre = RxNode;
		RxNode->next = HeadNode;
		RxNode->pre = HeadNode;
	}
	else
	{
		HeadNode->pre->next = RxNode;
		RxNode->pre = HeadNode->pre;
		HeadNode->pre = RxNode;
		RxNode->next = HeadNode;
	}
	card->RxQueueCount++;
	rt_hw_interrupt_enable(level);

done:
	return;
}
Beispiel #13
0
/***************************************************************************//**
 * @brief
 *  USART RX data valid interrupt handler
 *
 * @details
 *
 * @note
 *  9-bit SPI mode has not implemented yet and SPI slave mode is untested
 *
 * @param[in] dev
 *  Pointer to device descriptor
 ******************************************************************************/
void rt_hw_usart_rx_isr(rt_device_t dev)
{
    struct efm32_usart_device_t     *usart;
    struct efm32_usart_int_mode_t   *int_rx;
    rt_uint32_t                     flag;

    /* interrupt mode receive */
    RT_ASSERT(dev->flag & RT_DEVICE_FLAG_INT_RX);
    usart = (struct efm32_usart_device_t *)(dev->user_data);
    int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
    RT_ASSERT(int_rx->data_ptr != RT_NULL);
#if defined(UART_PRESENT)
    if (usart->state & USART_STATE_ASYNC_ONLY)
    {
        flag = UART_STATUS_RXDATAV;
    }
    else
#endif
    {
        flag = USART_STATUS_RXDATAV;
    }

    /* Set status */
    usart->state |= USART_STATE_RX_BUSY;

    /* save into rx buffer */
    while (usart->usart_device->STATUS & flag)
    {
        rt_base_t level;

        /* disable interrupt */
        level = rt_hw_interrupt_disable();

        /* save character */
        int_rx->data_ptr[int_rx->save_index] = \
                                               (rt_uint8_t)(usart->usart_device->RXDATA & 0xFFUL);
        int_rx->save_index ++;
        if (int_rx->save_index >= USART_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 >= USART_RX_BUFFER_SIZE)
            {
                int_rx->read_index = 0;
            }
        }

        /* enable interrupt */
        rt_hw_interrupt_enable(level);
    }

    /* invoke callback */
    if (dev->rx_indicate != RT_NULL)
    {
        rt_size_t rx_length;

        /* get rx length */
        rx_length = int_rx->read_index > int_rx->save_index ?
                    USART_RX_BUFFER_SIZE - int_rx->read_index + int_rx->save_index : \
                    int_rx->save_index - int_rx->read_index;

        dev->rx_indicate(dev, rx_length);
    }
}
Beispiel #14
0
/***************************************************************************//**
 * @brief
 *  Read from USART device
 *
 * @details
 *
 * @note
 *  9-bit SPI mode and SPI slave mode is untested
 *
 * @param[in] dev
 *  Pointer to device descriptor
 *
 * @param[in] pos
 *  Offset
 *
 * @param[in] buffer
 *  Poniter to the buffer
 *
 * @param[in] size
 *  Buffer size in byte
 *
 * @return
 *  Number of read bytes
 ******************************************************************************/
static rt_size_t rt_usart_read (
    rt_device_t     dev,
    rt_off_t        pos,
    void            *buffer,
    rt_size_t       size)
{
    rt_err_t    err_code;
    struct efm32_usart_device_t *usart;
    rt_size_t   read_len, len;
    rt_uint8_t  *ptr;
    rt_uint32_t rx_flag, tx_flag, b8_flag;

    usart = (struct efm32_usart_device_t *)(dev->user_data);
#if defined(UART_PRESENT)
    if (usart->state & USART_STATE_ASYNC_ONLY)
    {
        rx_flag = UART_STATUS_RXDATAV;
        tx_flag = UART_STATUS_TXBL;
        b8_flag = UART_CTRL_BIT8DV;
    }
    else
#endif
    {
        rx_flag = USART_STATUS_RXDATAV;
        tx_flag = USART_STATUS_TXBL;
        b8_flag = USART_CTRL_BIT8DV;
    }

    /* Lock device */
    if (rt_hw_interrupt_check())
    {
        err_code = rt_sem_take(usart->lock, RT_WAITING_NO);
    }
    else
    {
        err_code = rt_sem_take(usart->lock, RT_WAITING_FOREVER);
    }
    if (err_code != RT_EOK)
    {
        rt_set_errno(err_code);
        return 0;
    }

    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
    {
        len = size;
        ptr = buffer;
        /* interrupt mode Rx */
        while (len)
        {
            rt_base_t level;
            struct efm32_usart_int_mode_t *int_rx;

            int_rx = (struct efm32_usart_int_mode_t *)\
                     (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode);

            /* 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];
                len--;

                /* move to next position */
                int_rx->read_index ++;
                if (int_rx->read_index >= USART_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_len = (rt_uint32_t)ptr - (rt_uint32_t)buffer;
    }
    else
    {
        if (usart->state & USART_STATE_SYNC)
        {
            /* SPI read */
            rt_uint8_t inst_len = *((rt_uint8_t *)buffer);
            rt_uint8_t *inst_ptr = (rt_uint8_t *)(buffer + 1);
            rt_uint8_t *rx_buf = *((rt_uint8_t **)(buffer + inst_len + 1));
            rt_off_t i;

            ptr = inst_ptr;
            len = inst_len;
            /* Write instructions */
            if (len)
            {
                if (usart->state & USART_STATE_9BIT)
                {
                    usart->usart_device->CTRL &= ~b8_flag;
                }
                while (len)
                {
                    while (!(usart->usart_device->STATUS & tx_flag));
                    usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++);
                    len--;
                }
                if (usart->state & USART_STATE_9BIT)
                {
                    usart->usart_device->CTRL |= b8_flag;
                }
            }

            /* Flushing RX */
            usart->usart_device->CMD = USART_CMD_CLEARRX;
            /* Skip some bytes if necessary */
            for (i = 0; i < pos; i++)
            {
                /* dummy write */
                while (!(usart->usart_device->STATUS & tx_flag));
                usart->usart_device->TXDATA = (rt_uint32_t)0xff;
                /* dummy read */
                while (!(usart->usart_device->STATUS & rx_flag));
                *((rt_uint32_t *)0x00) = usart->usart_device->RXDATA;
            }

            ptr = rx_buf;
            len = size;
            /* Read data */
            while (len)
            {
                /* dummy write */
                while (!(usart->usart_device->STATUS & tx_flag));
                usart->usart_device->TXDATA = (rt_uint32_t)0xff;
                /* read a byte of data */
                while (!(usart->usart_device->STATUS & rx_flag));
                *(ptr++) = usart->usart_device->RXDATA & 0xff;
                len--;
            }
        }
        else
        {
            ptr = buffer;
            len = size;
            /* polling mode */
            while (len)
            {
                while (usart->usart_device->STATUS & rx_flag)
                {
                    *(ptr++) = usart->usart_device->RXDATA & 0xff;
                }
                len--;
            }
        }

        read_len = size - len;
    }

    /* Unlock device */
    rt_sem_release(usart->lock);

    /* set error code */
    rt_set_errno(err_code);

    return read_len;
}
Beispiel #15
0
void rt_timer_check(void)
{
	struct rt_timer *t;
	rt_tick_t current_tick;
	register rt_base_t level;

#ifdef RT_TIMER_DEBUG
	rt_kprintf("timer check enter\n");
#endif

	current_tick = rt_tick_get();

	/* disable interrupt */
	level = rt_hw_interrupt_disable();

	while (!rt_list_isempty(&rt_timer_list))
	{
		t = rt_list_entry(rt_timer_list.next, struct rt_timer, list);
		
		/*
		 * It supposes that the new tick shall less than the half duration of tick max.
		 */
		if ((current_tick - t->timeout_tick) < RT_TICK_MAX/2)
		{
#ifdef RT_USING_HOOK
			if (rt_timer_timeout_hook != RT_NULL) rt_timer_timeout_hook(t);
#endif

			/* remove timer from timer list firstly */
			rt_list_remove(&(t->list));

			/* call timeout function */
			t->timeout_func(t->parameter);

			/* re-get tick */
			current_tick = rt_tick_get();

#ifdef RT_TIMER_DEBUG
			rt_kprintf("current tick: %d\n", current_tick);
#endif

			if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
					(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
			{
				/* start it */
				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
				rt_timer_start(t);
			}
			else
			{
				/* stop timer */
				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
			}
		}
		else break;
	}

	/* enable interrupt */
	rt_hw_interrupt_enable(level);

	/* increase soft timer tick */
#ifdef RT_USING_TIMER_SOFT
	rt_soft_timer_tick_increase ( );
#endif

#ifdef RT_TIMER_DEBUG
	rt_kprintf("timer check leave\n");
#endif
}
static void net_buf_do_job(struct net_buffer_job* job)
{
	rt_uint32_t level;
    rt_size_t read_length, data_length;
	rt_uint8_t *ptr;

	ptr = rt_malloc(NETBUF_BLOCK_SIZE);

    while (1)
    {
    	if (_netbuf.stat == NETBUF_STAT_STOPPING)
    	{
    		net_buf_do_stop(job);
            break;
    	}

    	/* fetch data buffer */
		read_length = job->fetch(ptr, NETBUF_BLOCK_SIZE, job->parameter);
		if (read_length <= 0)
		{
			net_buf_do_stop(job);
            break;
		}
		else
		{
			/* got data length in the buffer */
			data_length = _netbuf.data_length;

			/* check avaible buffer to save */
			if ((_netbuf.size - data_length) < read_length)
			{
				rt_err_t result, level;

				/* no free space yet, suspend itself */
				// rt_kprintf("stat[buffering] -> suspend, avaible room %d\n", data_length);
				level = rt_hw_interrupt_disable();
				_netbuf.stat = NETBUF_STAT_SUSPEND;
				rt_hw_interrupt_enable(level);
				result = rt_sem_take(_netbuf.wait_resume, RT_WAITING_FOREVER);
				if (result != RT_EOK)
				{
					/* stop net buffer worker */
					net_buf_do_stop(job);
					break;
				}
			}

			/* there are enough free space to fetch data */
	        if ((_netbuf.size - _netbuf.save_index) < read_length)
	        {
	        	rt_memcpy(&_netbuf.buffer_data[_netbuf.save_index],
					ptr, _netbuf.size - _netbuf.save_index);
				rt_memcpy(&_netbuf.buffer_data[0],
					ptr + (_netbuf.size - _netbuf.save_index),
					read_length - (_netbuf.size - _netbuf.save_index));

				/* move save index */
				_netbuf.save_index = read_length - (_netbuf.size - _netbuf.save_index);
	        }
	        else
	        {
	        	rt_memcpy(&_netbuf.buffer_data[_netbuf.save_index],
					ptr, read_length);

				/* move save index */
				_netbuf.save_index += read_length;
				if (_netbuf.save_index >= _netbuf.size) _netbuf.save_index = 0;
	        }

			level = rt_hw_interrupt_disable();
			_netbuf.data_length += read_length;
			data_length = _netbuf.data_length;
			rt_hw_interrupt_enable(level);
		}

		if ((_netbuf.stat == NETBUF_STAT_BUFFERING) 
			&& (data_length >= _netbuf.ready_wm) 
			&& _netbuf.is_wait_ready == RT_TRUE)
		{
			/* notify the thread for waitting buffer ready */
			rt_kprintf("resume wait buffer\n");

			_netbuf.is_wait_ready = RT_FALSE;
			/* set buffer status to playing */
			player_set_buffer_status(RT_FALSE);
			rt_sem_release(_netbuf.wait_ready);
		}
    }

	/* release fetch buffer */
	rt_free(ptr);
}
Beispiel #17
0
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
    rt_uint8_t *ptr;
    rt_err_t err_code;
    struct avr32_serial_device *uart;

    ptr = buffer;
    err_code = RT_EOK;
    uart = (struct avr32_serial_device *)dev->user_data;

    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
    {
        /* interrupt mode Rx */
        while (size)
        {
            rt_base_t level;

            /* disable interrupt */
            level = rt_hw_interrupt_disable();

            if (uart->int_rx->read_index != uart->int_rx->save_index)
            {
                /* read a character */
                *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
                size--;

                /* move to next position */
                uart->int_rx->read_index ++;
                if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
                    uart->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);
        }
    }
    else
    {
        /* polling mode */
        while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
        {
            while (usart_test_hit(uart->uart_device))
            {
                *ptr = uart->uart_device->rhr & 0xff;
                ptr ++;
            }
        }
    }

    /* set error code */
    rt_set_errno(err_code);
    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
/* netbuf worker public API */
rt_size_t net_buf_read(rt_uint8_t* buffer, rt_size_t length)
{
    rt_size_t data_length, read_index;
	rt_uint32_t level;

	data_length = _netbuf.data_length;

    if ((data_length == 0) &&
		(_netbuf.stat == NETBUF_STAT_BUFFERING || _netbuf.stat == NETBUF_STAT_SUSPEND))
    {
    	rt_err_t result;

        /* buffer is not ready. */
        _netbuf.is_wait_ready = RT_TRUE;
		rt_kprintf("wait ready, data len: %d, stat %d\n", data_length, _netbuf.stat);
		/* set buffer status to buffering */
		player_set_buffer_status(RT_TRUE);
        result = rt_sem_take(_netbuf.wait_ready, RT_WAITING_FOREVER);

		/* take semaphore failed, netbuf worker is stopped */
		if (result != RT_EOK) return 0;
    }

    /* get read and save index */
    read_index = _netbuf.read_index;
    /* re-get data legnth */
    data_length = _netbuf.data_length;

	/* set the length */
	if (length > data_length) length = data_length;

	// rt_kprintf("data len: %d, read idx %d\n", data_length, read_index);
    if (data_length > 0)
    {
        /* copy buffer */
        if (_netbuf.size - read_index > length)
        {
            rt_memcpy(buffer, &_netbuf.buffer_data[read_index],
                length);
			_netbuf.read_index += length;
        }
        else
        {
            rt_memcpy(buffer, &_netbuf.buffer_data[read_index],
                _netbuf.size - read_index);
            rt_memcpy(&buffer[_netbuf.size - read_index],
                &_netbuf.buffer_data[0],
                length - (_netbuf.size - read_index));
			_netbuf.read_index = length - (_netbuf.size - read_index);
        }

		/* update length of data in buffer */
		level = rt_hw_interrupt_disable();
		_netbuf.data_length -= length;
		data_length = _netbuf.data_length;

        if ((_netbuf.stat == NETBUF_STAT_SUSPEND) && data_length < _netbuf.resume_wm)
        {
        	_netbuf.stat = NETBUF_STAT_BUFFERING;
			rt_hw_interrupt_enable(level);

			/* resume netbuf worker */
			// rt_kprintf("stat[suspend] -> buffering\n");
            rt_sem_release(_netbuf.wait_resume);
        }
		else
		{
			rt_hw_interrupt_enable(level);
		}
    }
	
    return length;
}
static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
    rt_uint8_t* ptr;
    rt_err_t err_code;
    struct serial_device* uart;

    ptr = buffer;
    err_code = RT_EOK;
    uart = (struct serial_device*)dev->user_data;

    if (ptr == RT_NULL)
    {
        err_code = -RT_ENOMEM;
        rt_set_errno(err_code);
        return -RT_ENOMEM;
    }
    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
    {
        rt_base_t level;

        /* interrupt mode Rx */
        while (size)
        {
            if (uart->int_rx->read_index != uart->int_rx->save_index)
            {
                *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
                size --;

                /* disable interrupt */
                level = rt_hw_interrupt_disable();

                uart->int_rx->read_index ++;
                if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
                    uart->int_rx->read_index = 0;

                /* enable interrupt */
                rt_hw_interrupt_enable(level);
            }
            else
            {
                /* set error code */
                err_code = -RT_EEMPTY;
                break;
            }
        }
    }
    else
    {
        /* polling mode */
        while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
        {
            while (uart->uart_device->ustat & USTAT_RCV_READY)
            {
                *ptr = uart->uart_device->urxh & 0xff;
                ptr ++;
            }
        }
    }

    /* set error code */
    rt_set_errno(err_code);
    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
Beispiel #20
0
rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
    const struct pin_index *index;
    const struct pin_irq_map *irqmap;
    rt_base_t level;
    rt_int32_t hdr_index = -1;
    exti_trig_type_enum trigger_mode;

    index = get_pin(pin);
    if (index == RT_NULL)
    {
        return RT_EINVAL;
    }
    if (enabled == PIN_IRQ_ENABLE)
    {
        hdr_index = bit2bitno(index->pin);
        if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
        {
            return RT_EINVAL;
        }
        level = rt_hw_interrupt_disable();
        if (pin_irq_hdr_tab[hdr_index].pin == -1)
        {
            rt_hw_interrupt_enable(level);
            return RT_EINVAL;
        }
        irqmap = &pin_irq_map[hdr_index];
   
        switch (pin_irq_hdr_tab[hdr_index].mode)
        {
            case PIN_IRQ_MODE_RISING:
                trigger_mode = EXTI_TRIG_RISING;
                break;
            case PIN_IRQ_MODE_FALLING:
                trigger_mode = EXTI_TRIG_FALLING;
                break;
            case PIN_IRQ_MODE_RISING_FALLING:
                trigger_mode = EXTI_TRIG_BOTH;
                break;
            default:
                rt_hw_interrupt_enable(level);
                return RT_EINVAL;
        }

        //rcu_periph_clock_enable(RCU_AF);

        /* enable and set interrupt priority */
        nvic_irq_enable(irqmap->irqno, 5U);
        
        /* connect EXTI line to  GPIO pin */
				syscfg_exti_line_config(index->port_src, index->pin_src);

        /* configure EXTI line */
        exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode);
        exti_interrupt_flag_clear((exti_line_enum)(index->pin));
        
        rt_hw_interrupt_enable(level);
    }
    else if (enabled == PIN_IRQ_DISABLE)
    {
        irqmap = get_pin_irq_map(index->pin);
        if (irqmap == RT_NULL)
        {
            return RT_EINVAL;
        }
        nvic_irq_disable(irqmap->irqno);
    }
    else
    {
        return RT_EINVAL;
    }

    return RT_EOK;
}
Beispiel #21
0
/**
 * This function will take a mutex, if the mutex is unavailable, the
 * thread shall wait for a specified time.
 *
 * @param mutex the mutex object
 * @param time the waiting time
 *
 * @return the error code
 */
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
{
	register rt_base_t temp;
	struct rt_thread *thread;

	/* this function must not be used in interrupt even if time = 0 */
	RT_DEBUG_NOT_IN_INTERRUPT;

	RT_ASSERT(mutex != RT_NULL);

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

	/* get current thread */
	thread = rt_thread_self();

	RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mutex->parent.parent)));

	RT_DEBUG_LOG(RT_DEBUG_IPC,
		("mutex_take: current thread %s, mutex value: %d, hold: %d\n",
		thread->name, mutex->value, mutex->hold));

	/* reset thread error */
	thread->error = RT_EOK;

	if (mutex->owner == thread)
	{
		/* it's the same thread */
		mutex->hold ++;
	}
	else
	{
		/* in initialization status, the value is 1. Therefore, if the
		 * value is great than 1, which indicates the mutex is avaible.
		 */
		if (mutex->value > 0)
		{
			/* mutex is available */
			mutex->value --;

			/* set mutex owner and original priority */
			mutex->owner = thread;
			mutex->original_priority = thread->current_priority;
			mutex->hold ++;
		}
		else
		{
			/* no waiting, return with timeout */
			if (time == 0)
			{
				/* set error as timeout */
				thread->error = -RT_ETIMEOUT;

				/* enable interrupt */
				rt_hw_interrupt_enable(temp);

				return -RT_ETIMEOUT;
			}
			else
			{
				/* mutex is unavailable, push to suspend list */
				RT_DEBUG_LOG(RT_DEBUG_IPC,
					("mutex_take: suspend thread: %s\n", thread->name));

				/* change the owner thread priority of mutex */
				if (thread->current_priority < mutex->owner->current_priority)
				{
					/* change the owner thread priority */
					rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY,
						&thread->current_priority);
				}

				/* suspend current thread */
				rt_ipc_list_suspend(&(mutex->parent.suspend_thread),
				thread, mutex->parent.parent.flag);

				/* has waiting time, start thread timer */
				if (time > 0)
				{
					RT_DEBUG_LOG(RT_DEBUG_IPC,
						("mutex_take: start the timer of thread:%s\n", thread->name));

					/* reset the timeout of thread timer and start it */
					rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
					rt_timer_start(&(thread->thread_timer));
				}

				/* enable interrupt */
				rt_hw_interrupt_enable(temp);

				/* do schedule */
				rt_schedule();

				if (thread->error != RT_EOK)
				{
					/* return error */
					return thread->error;
				}
				else
				{
					/* the mutex is taken successfully. */
					/* disable interrupt */
					temp = rt_hw_interrupt_disable();
				}
			}
		}
	}

	/* enable interrupt */
	rt_hw_interrupt_enable(temp);

	RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mutex->parent.parent)));

	return RT_EOK;
}
Beispiel #22
0
rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin,
                               rt_uint32_t enabled)
{
    const struct pin_index *index;
    const struct pin_irq_map *irqmap;
    rt_base_t level;
    rt_int32_t irqindex = -1;
    /*Configure GPIO_InitStructure & EXTI_InitStructure*/
    gpio_init_t gpio_initstruct;
    exti_init_t exti_initstruct;
    exti_initstruct.filter = DISABLE;
    exti_initstruct.cks = EXTI_FILTER_CLOCK_10K;
    exti_initstruct.filter_time = 0x0;

    index = get_pin(pin);
    if (index == RT_NULL)
    {
        return RT_ENOSYS;
    }
    if (enabled == PIN_IRQ_ENABLE)
    {
        /**pin no. convert to dec no.**/
        for (irqindex = 0; irqindex < 16; irqindex++)
        {
            if ((0x01 << irqindex) == index->pin)
            {
                break;
            }
        }
        if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
        {
            return RT_ENOSYS;
        }
        level = rt_hw_interrupt_disable();
        if (pin_irq_hdr_tab[irqindex].pin == -1)
        {
            rt_hw_interrupt_enable(level);
            return RT_ENOSYS;
        }
        irqmap = &pin_irq_map[irqindex];
        gpio_exti_init(index->gpio, index->pin, &exti_initstruct);
        /* Configure GPIO_InitStructure */
        gpio_initstruct.mode = GPIO_MODE_INPUT;
        gpio_initstruct.func = GPIO_FUNC_1;
        switch (pin_irq_hdr_tab[irqindex].mode)
        {
        case PIN_IRQ_MODE_RISING:
            gpio_initstruct.pupd = GPIO_PUSH_DOWN;
            gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_RISING_EDGE, ENABLE);
            break;
        case PIN_IRQ_MODE_FALLING:
            gpio_initstruct.pupd = GPIO_PUSH_UP;
            gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_TRAILING_EDGE, ENABLE);
            break;
        case PIN_IRQ_MODE_RISING_FALLING:
            gpio_initstruct.pupd = GPIO_FLOATING;
            gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_BOTH_EDGE, ENABLE);
            break;
        }
        gpio_init(index->gpio, index->pin, &gpio_initstruct);
        NVIC_EnableIRQ(irqmap->irqno);
        rt_hw_interrupt_enable(level);
    }
    else if (enabled == PIN_IRQ_DISABLE)
    {
        irqmap = get_pin_irq_map(index->pin);
        if (irqmap == RT_NULL)
        {
            return RT_ENOSYS;
        }
        NVIC_DisableIRQ(irqmap->irqno);
    }
    else
    {
        return RT_ENOSYS;
    }
    return RT_EOK;
}
Beispiel #23
0
/***************************************************************************//**
 * @brief
 *   Read from IIC device
 *
 * @details
 *
 * @note
 *
 * @param[in] dev
 *   Pointer to device descriptor
 *
 * @param[in] pos
 *   Slave address
 *
 * @param[in] buffer
 *   Poniter to the buffer
 *
 * @param[in] size
 *   Buffer size in byte
 *
 * @return
 *   Error code
 ******************************************************************************/
static rt_size_t rt_iic_read (
    rt_device_t     dev,
    rt_off_t        pos,
    void*           buffer,
    rt_size_t       size)
{
    rt_err_t                    err_code;
    rt_size_t                   read_size;
    struct efm32_iic_device_t*  iic;
    I2C_TransferSeq_TypeDef     seq;
    I2C_TransferReturn_TypeDef  ret;

    if (!size)
    {
        return 0;
    }

    err_code = RT_EOK;
    read_size = 0;
    iic = (struct efm32_iic_device_t*)dev->user_data;

    /* Lock device */
    if (rt_hw_interrupt_check())
    {
        ret = rt_sem_take(iic->lock, RT_WAITING_NO);
    }
    else
    {
        ret = rt_sem_take(iic->lock, RT_WAITING_FOREVER);
    }
    if (ret != RT_EOK)
    {
        return ret;
    }

    if (iic->state & IIC_STATE_MASTER)
    {
        seq.addr = (rt_uint16_t)pos << 1;
        if (*(rt_uint8_t *)buffer == IIC_OP_READ_ONLY)
        {
            seq.flags = I2C_FLAG_READ;
            /* Set read buffer pointer and size */
            seq.buf[0].data = (rt_uint8_t *)buffer;
            seq.buf[0].len = size;
        }
        else
        {
            seq.flags = I2C_FLAG_WRITE_READ;
            /* Set register to be read */
            seq.buf[0].data = (rt_uint8_t *)buffer;
            seq.buf[0].len = 1;
            /* Set read buffer pointer and size */
            seq.buf[1].data = (rt_uint8_t *)buffer;
            seq.buf[1].len = size;
        }

        /* Do a polled transfer */
        iic->timeout = false;
        rt_timer_stop(iic->timer);
        rt_timer_start(iic->timer);
        ret = I2C_TransferInit(iic->iic_device, &seq);
        while ((ret == i2cTransferInProgress) && !iic->timeout)
        {
          ret = I2C_Transfer(iic->iic_device);
        }

        if (ret != i2cTransferDone)
        {
            iic_debug("IIC: read error %x\n", ret);
            iic_debug("IIC: read address %x\n", seq.addr);
            iic_debug("IIC: read data0 %x -> %x\n", seq.buf[0].data, *seq.buf[0].data);
            iic_debug("IIC: read len0 %x\n", seq.buf[0].len);
            iic_debug("IIC: read data1 %x -> %x\n", seq.buf[1].data, *seq.buf[1].data);
            iic_debug("IIC: read len1 %x\n", seq.buf[1].len);
            err_code = (rt_err_t)ret;
        }
        else
        {
            read_size = size;
            iic_debug("IIC: read size %d\n", read_size);
        }
    }
    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;
        iic_debug("IIC: slave read size %d\n", read_size);
    }

    /* Unlock device */
    rt_sem_release(iic->lock);

    /* set error code */
    rt_set_errno(err_code);
    return read_size;
}
Beispiel #24
0
/**
 * This function will perform one schedule. It will select one thread
 * with the highest priority level, then switch to it.
 */
void rt_schedule(void)
{
    rt_base_t level;
    struct rt_thread *to_thread;
    struct rt_thread *from_thread;

    /* disable interrupt */
    level = rt_hw_interrupt_disable();

    /* check the scheduler is enabled or not */
    if (rt_scheduler_lock_nest == 0)
    {
        register rt_ubase_t highest_ready_priority;

#if RT_THREAD_PRIORITY_MAX <= 32
        highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
#else
        register rt_ubase_t number;

        number = __rt_ffs(rt_thread_ready_priority_group) - 1;
        highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
#endif

        /* get switch to thread */
        to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,
                                  struct rt_thread,
                                  tlist);

        /* if the destination thread is not the same as current thread */
        if (to_thread != rt_current_thread)
        {
            rt_current_priority = (rt_uint8_t)highest_ready_priority;
            from_thread         = rt_current_thread;
            rt_current_thread   = to_thread;

            RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread));

            /* switch to new thread */
            RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
                         ("[%d]switch to priority#%d "
                          "thread:%.*s(sp:0x%p), "
                          "from thread:%.*s(sp: 0x%p)\n",
                          rt_interrupt_nest, highest_ready_priority,
                          RT_NAME_MAX, to_thread->name, to_thread->sp,
                          RT_NAME_MAX, from_thread->name, from_thread->sp));

#ifdef RT_USING_OVERFLOW_CHECK
            _rt_scheduler_stack_check(to_thread);
#endif

            if (rt_interrupt_nest == 0)
            {
                extern void rt_thread_handle_sig(rt_bool_t clean_state);

                rt_hw_context_switch((rt_uint32_t)&from_thread->sp,
                                     (rt_uint32_t)&to_thread->sp);

                /* enable interrupt */
                rt_hw_interrupt_enable(level);

#ifdef RT_USING_SIGNALS
                /* check signal status */
                rt_thread_handle_sig(RT_TRUE);
#endif
            }
            else
            {
                RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n"));

                rt_hw_context_switch_interrupt((rt_uint32_t)&from_thread->sp,
                                               (rt_uint32_t)&to_thread->sp);
                /* enable interrupt */
                rt_hw_interrupt_enable(level);
            }
        }
        else 
        {
            /* enable interrupt */
            rt_hw_interrupt_enable(level);
        }
    }
    else
    {
/* ISR for serial interrupt */
void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
{
    switch (event & 0xff)
    {
        case RT_SERIAL_EVENT_RX_IND:
        {
            int ch = -1;
            rt_base_t level;
            struct rt_serial_rx_fifo* rx_fifo;

            /* interrupt mode receive */
            rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
            RT_ASSERT(rx_fifo != RT_NULL);

            while (1)
            {
                ch = serial->ops->getc(serial);
                if (ch == -1) break;

                
                /* disable interrupt */
                level = rt_hw_interrupt_disable();
                
                rx_fifo->buffer[rx_fifo->put_index] = ch;
                rx_fifo->put_index += 1;
                if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
                
                /* if the next position is read index, discard this 'read char' */
                if (rx_fifo->put_index == rx_fifo->get_index)
                {
                    rx_fifo->get_index += 1;
                    if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
                }
                
                /* enable interrupt */
                rt_hw_interrupt_enable(level);
            }
            
            /* invoke callback */
            if (serial->parent.rx_indicate != RT_NULL)
            {
                rt_size_t rx_length;
            
                /* get rx length */
                level = rt_hw_interrupt_disable();
                rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
                    (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
                rt_hw_interrupt_enable(level);

                serial->parent.rx_indicate(&serial->parent, rx_length);
            }
            break;
        }
        case RT_SERIAL_EVENT_TX_DONE:
        {
            struct rt_serial_tx_fifo* tx_fifo;

            tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
            rt_completion_done(&(tx_fifo->completion));
            break;
        }
        case RT_SERIAL_EVENT_TX_DMADONE:
        {
            const void *data_ptr;
            rt_size_t data_size;
            const void *last_data_ptr;
            struct rt_serial_tx_dma* tx_dma;

            tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
            
            rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0);
            if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
            {
                /* transmit next data node */
                tx_dma->activated = RT_TRUE;
                serial->ops->dma_transmit(serial, data_ptr, data_size, RT_SERIAL_DMA_TX);
            }
            else
            {
                tx_dma->activated = RT_FALSE;
            }
            
            /* invoke callback */
            if (serial->parent.tx_complete != RT_NULL)
            {
                serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr);
            }
            break;
        }
        case RT_SERIAL_EVENT_RX_DMADONE:
        {
            int length;
            struct rt_serial_rx_dma* rx_dma;

            rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
            /* get DMA rx length */
            length = (event & (~0xff)) >> 8;
            serial->parent.rx_indicate(&(serial->parent), length);
            rx_dma->activated = RT_FALSE;
            break;
        }
    }
}
Beispiel #26
0
/* ISR for serial interrupt */
void rt_hw_serial_isr(rt_device_t device)
{
    struct stm32_serial_device* uart = (struct stm32_serial_device*) device->user_data;
    static unsigned char checksum = 0;
    static uint16_t lenth;
    // static unsigned char gprmcbuf[400];
    static unsigned char isgprmc=0;
    static unsigned short gprmccnt = 0;

    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
    {
        /* interrupt mode receive */
        RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);

        /* save on rx buffer */
        while (uart->uart_device->SR & USART_FLAG_RXNE)
        {
            rt_base_t level;

            /* disable interrupt */
            level = rt_hw_interrupt_disable();

            /* save character */

            if((&uart2_device )== device)
            {
                uartcount++;
                uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->DR & 0xff;
                rt_device_write(&uart2_device, 0,&(uart->int_rx->rx_buffer[uart->int_rx->save_index]), 1);
                checksum = checksum^(uart->int_rx->rx_buffer[uart->int_rx->save_index]);
                switch (Uart2PackStatus )
                {
                case Get_sync_head:
                    if ((uart->int_rx->rx_buffer[uart->int_rx->save_index])== 0xaa)
                    {
                        checksum = uart->int_rx->rx_buffer[uart->int_rx->save_index];
                        Uart2PackStatus = Start_head_end;
                    }
                    else
                    {
                        uart->int_rx->getcmd = 0x7f;
                    }
                    break;
                case Start_head_end:
                    if((uart->int_rx->rx_buffer[uart->int_rx->save_index])== 0x75)
                    {
                        Uart2PackStatus = Get_the_Command;
                        //rt_device_write(&uart2_device, 0,&(uart->int_rx->rx_buffer[uart->int_rx->save_index]), 1);
                    }
                    else
                    {
                        uart->int_rx->getcmd = 0x7f;
                        Uart2PackStatus = Get_sync_head;
                    }
                    break;
                case Get_the_Command:
                    if(((uart->int_rx->rx_buffer[uart->int_rx->save_index]) <0x16)
                            ||((uart->int_rx->rx_buffer[uart->int_rx->save_index])>0x81
                               &&(uart->int_rx->rx_buffer[uart->int_rx->save_index])<0x85 )
                            ||((uart->int_rx->rx_buffer[uart->int_rx->save_index])>0x81
                               &&(uart->int_rx->rx_buffer[uart->int_rx->save_index])<0x85 )
                            ||((uart->int_rx->rx_buffer[uart->int_rx->save_index])>0xc1
                               &&(uart->int_rx->rx_buffer[uart->int_rx->save_index])<0xc5 ))
                    {
                        Uart2PackStatus = Get_the_lenth_high;
                    }
                    else
                    {
                        uart->int_rx->getcmd = 0x7f;
                        Uart2PackStatus = Get_sync_head;
                    }

                    break;
                case Get_the_lenth_high:
                    lenth = uart->int_rx->rx_buffer[uart->int_rx->save_index];
                    Uart2PackStatus = Get_the_lenth_low;
                    break;
                case Get_the_lenth_low:
                    lenth = ((lenth<<8)&0xff00)+(uart->int_rx->rx_buffer[uart->int_rx->save_index]);
                    Uart2PackStatus = Get_the_reserve;
                    break;
                case Get_the_reserve:
                    if (lenth != 0)
                    {
                        Uart2PackStatus = Get_the_data;
                    }
                    else
                        Uart2PackStatus = Get_the_checksum;
                    break;
                case Get_the_data:
                    if(lenth )
                        lenth--;
                    if(lenth == 0)
                        Uart2PackStatus = Get_the_checksum;

                    break;
                case Get_the_checksum:
                    if(checksum == 0)
                    {
                        uart->int_rx->getcmd ++;
                    }
                    else
                    {
                        uart->int_rx->getcmd = 0x7f;
                    }
                    Uart2PackStatus = Get_sync_head;
                    break;
                default:
                    break;
                }

                uart->int_rx->save_index ++;
                if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
                    uart->int_rx->save_index = 0;

                /* if the next position is read index, discard this 'read char' */
                if (uart->int_rx->save_index == uart->int_rx->read_index)
                {
                    uart->int_rx->read_index ++;
                    if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
                        uart->int_rx->read_index = 0;
                }

            }
            if((&uart3_device)== device)
            {
                if((uart->uart_device->DR & 0xff) == '$')
                {

                    SectionID=0;
                    isgprmc = 0;
                    gprmccnt =0;
                    uart3flag =1;
                }
                else if((uart->uart_device->DR & 0xff)==',')
                {
                    if((isgprmc == 1)&&(SectionID== FIELD_NIGHT))
                    {
                        //get the time
                        GetGPSLocation3(gprmcbuf,gprmccnt);
                    }
                    else if((isgprmc == 2) &&(SectionID == FIELD_SEVEN ))
                    {
                        GetGPSSpeed(gprmcbuf,gprmccnt);

                    }
                    SectionID++;
                    gprmccnt = 0;
                    uart3flag =2;

                }

                else
                {
                    if(gprmccnt == 400)
                    {
                        gprmccnt = 0;
                    }
                    gprmcbuf[gprmccnt] = uart->uart_device->DR & 0xff;
                    gprmccnt++;
                    switch(SectionID)
                    {
                    case FIELD_NONE:
                        if(gprmccnt == 5)
                        {
                            uart3flag =2;
                            gprmccnt =0 ;
                            if ( (gprmcbuf[0] == 'G')
                                    &&(gprmcbuf[1] == 'P')&&(gprmcbuf[2] =='G')
                                    &&(gprmcbuf[3] =='G')&&(gprmcbuf[4] == 'A'))
                            {
                                isgprmc =1;//位置信息

                            }
                            if ( (gprmcbuf[0] == 'G')
                                    &&(gprmcbuf[1] == 'P')&&(gprmcbuf[2] =='V')
                                    &&(gprmcbuf[3] == 'T')&&(gprmcbuf[4] == 'G'))
                            {
                                isgprmc =2;//速度信息
                                uart3flag =2;
                            }
                        }

                        break;
                    case FIELD_ONE://提取时间
                        uart3flag =1;
                        if(isgprmc == 1)
                        {
                            if(gprmccnt == 10  )
                            {
                                //get the time
                                GetTheGPSTime(gprmcbuf);
                            }
                        }
                        break;
                    case FIELD_TWO: //判断数据是否可信(当GPS天线能接收到有3颗GPS卫星时为A,可信
                        if(isgprmc == 1)
                        {
                            if(gprmccnt == 9 )
                            {
                                //get the time
                                GetGPSLocation1(gprmcbuf);
                            }
                        }
                        break;
                    case FIELD_THREE://提取出纬度
                        break;
                    case FIELD_FOUR://提取出速度
                        if(isgprmc == 1)
                        {
                            if(gprmccnt == 10 )
                            {
                                //get the time
                                GetGPSLocation2(gprmcbuf);
                            }
                        }
                        break;
                    case FIELD_FIVE://提取出经度
                        break;
                    case FIELD_SEVEN:
                        if(isgprmc == 1)
                        {
                            if(gprmccnt == 2 )
                            {
                                //get the singal
                                GettheSinaldata(gprmcbuf);
                            }
                        }
                        break;
                    case FIELD_NIGHT://提取高度
                        break;
                    default:
                        break;
                    }
                }
            }
            if((&uart4_device )== device)
            {
                gprmcbuf[gprmccnt] = uart->uart_device->DR & 0xff;
                gprmccnt++;
            }

            /* enable interrupt */
            rt_hw_interrupt_enable(level);
        }

        /* clear interrupt */
        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);

        /* invoke callback */
        if (device->rx_indicate != RT_NULL)
        {
            rt_size_t rx_length;

            /* get rx length */
            rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
                        UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
                        uart->int_rx->save_index - uart->int_rx->read_index;

            device->rx_indicate(device, rx_length);
        }
    }

    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
    {
        /* clear interrupt */
        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
    }
}
Beispiel #27
0
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
	rt_uint8_t* ptr;
	rt_err_t err_code;
	struct stm32_serial_device* uart;

	err_code = RT_EOK;
	ptr = (rt_uint8_t*)buffer;
	uart = (struct stm32_serial_device*)dev->user_data;

	if (dev->flag & RT_DEVICE_FLAG_INT_TX)
	{
		/* interrupt mode Tx, does not support */
		RT_ASSERT(0);
	}
	else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
	{
		/* DMA mode Tx */

		/* allocate a data node */
		struct stm32_serial_data_node* data_node = (struct stm32_serial_data_node*)
			rt_mp_alloc (&(uart->dma_tx->data_node_mp), RT_WAITING_FOREVER);
		if (data_node == RT_NULL)
		{
			/* set error code */
			err_code = -RT_ENOMEM;
		}
		else
		{
			rt_uint32_t level;

			/* fill data node */
			data_node->data_ptr 	= ptr;
			data_node->data_size 	= size;

			/* insert to data link */
			data_node->next = RT_NULL;

			/* disable interrupt */
			level = rt_hw_interrupt_disable();

			data_node->prev = uart->dma_tx->list_tail;
			if (uart->dma_tx->list_tail != RT_NULL)
				uart->dma_tx->list_tail->next = data_node;
			uart->dma_tx->list_tail = data_node;

			if (uart->dma_tx->list_head == RT_NULL)
			{
				/* start DMA to transmit data */
				uart->dma_tx->list_head = data_node;

				/* Enable DMA Channel */
				rt_serial_enable_dma(uart->dma_tx->dma_channel,
					(rt_uint32_t)uart->dma_tx->list_head->data_ptr,
					uart->dma_tx->list_head->data_size);
			}

			/* enable interrupt */
			rt_hw_interrupt_enable(level);
		}
	}
	else
	{
		/* polling mode */
		if (dev->flag & RT_DEVICE_FLAG_STREAM)
		{
			/* stream mode */
			while (size)
			{
				if (*ptr == '\n')
				{
					while (!(uart->uart_device->SR & USART_FLAG_TXE));
					uart->uart_device->DR = '\r';
				}

				while (!(uart->uart_device->SR & USART_FLAG_TXE));
				uart->uart_device->DR = (*ptr & 0x1FF);

				++ptr; --size;
			}
		}
		else
		{
			/* write data directly */
			while (size)
			{
				while (!(uart->uart_device->SR & USART_FLAG_TXE));
				uart->uart_device->DR = (*ptr & 0x1FF);

				++ptr; --size;
			}
		}
	}

	/* set error code */
	rt_set_errno(err_code);

	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
Beispiel #28
0
rt_err_t rt_completion_wait(struct rt_completion *completion,
                            rt_int32_t            timeout)
{
    rt_err_t result;
    rt_base_t level;
    rt_thread_t thread;
    RT_ASSERT(completion != RT_NULL);

    result = RT_EOK;
    thread = rt_thread_self();

    level = rt_hw_interrupt_disable();
    if (completion->flag != RT_COMPLETED)
    {
        /* only one thread can suspend on complete */
        RT_ASSERT(rt_list_isempty(&(completion->suspended_list)));

        if (timeout == 0)
        {
            result = -RT_ETIMEOUT;
            goto __exit;
        }
        else
        {
            /* reset thread error number */
            thread->error = RT_EOK;

            /* suspend thread */
            rt_thread_suspend(thread);
            /* add to suspended list */
            rt_list_insert_before(&(completion->suspended_list),
                                  &(thread->tlist));

            /* current context checking */
            RT_DEBUG_NOT_IN_INTERRUPT;

            /* start timer */
            if (timeout > 0)
            {
                /* reset the timeout of thread timer and start it */
                rt_timer_control(&(thread->thread_timer),
                                 RT_TIMER_CTRL_SET_TIME,
                                 &timeout);
                rt_timer_start(&(thread->thread_timer));
            }
            /* enable interrupt */
            rt_hw_interrupt_enable(level);

            /* do schedule */
            rt_schedule();

            /* thread is waked up */
            result = thread->error;

            level = rt_hw_interrupt_disable();
            /* clean completed flag */
            completion->flag = RT_UNCOMPLETED;
        }
    }

__exit:
    rt_hw_interrupt_enable(level);

    return result;
}