Exemple #1
0
void tkControl(void * pvParameters)
{

( void ) pvParameters;
BaseType_t xResult;
uint32_t ulNotifiedValue;

	MCP_init();

	// TERMINAL: Debe ser lo primero que incia para poder mandar mensajes de log.
	ac_terminal(INIT_TERM, NULL);

	loadSystemParams();

	// WATCHDOG
	ac_wdg( INIT_WDG );

	// LEDS
	ac_systemLeds( INIT_LED );

	// EXITWRKMODE2NORMAL
	ac_exitWrkMode2Normal(INIT_EWM2N);

	// MEMORIA
	MEM_init();
	snprintf_P( ctl_printfBuff,CHAR256,PSTR("Init memory: pWr=%d,pRd=%d,pDel=%d,free=%d,4rd=%d,4del=%d  \r\n"), MEM_getWrPtr(), MEM_getRdPtr(), MEM_getDELptr(), MEM_getRcdsFree(),MEM_getRcds4rd(),MEM_getRcds4del() );
	TERMrprintfStr( ctl_printfBuff );

	// Habilito arrancar otras tareas
	startToken = STOK_TIMERS;

	// Espero la notificacion para arrancar
	while ( startToken != STOK_CTL ) {
		vTaskDelay( ( TickType_t)( 100 / portTICK_RATE_MS ) );
	}
	TERMrprintfProgStrM("starting tkControl..\r\n");
	startToken++;

	// Loop
	for( ;; )
	{
		clearWdg(WDG_CTL);

		// LED
		ac_systemLeds(TOGGLE_LED);

		// WATCHDOG
		ac_wdg(CHECK_WDG);

		// TERMINAL
		ac_terminal(CHECK_TERM, NULL);

		// EXITWRKMODE2NORMAL
		ac_exitWrkMode2Normal(CHECK_EWM2N);

		// Genero una espera de 100ms por algun mensaje para hacer algo.
		xResult = xTaskNotifyWait( 0x00,          	 				/* Don't clear bits on entry. */
		                           ULONG_MAX,        				/* Clear all bits on exit. */
		                           &ulNotifiedValue, 				/* Stores the notified value. */
								   (100 / portTICK_RATE_MS ) );

		if( xResult == pdTRUE ) {
			// Arrancar el timer y control de modo service/monitor
			if ( ( ulNotifiedValue & CTLMSG_STARTEWM2N ) != 0 ) {
				ac_exitWrkMode2Normal(START_EWM2N);
		    }

		 }
	}
}
/**
 * \brief Main demo task
 *
 * This task keeps track of which screen the user has selected, which tasks
 * to resume/suspend to draw the selected screen, and also draws the menu bar.
 *
 * The menu bar shows which screens the user can select by clicking the
 * corresponding buttons on the OLED1 Xplained Pro:
 * - \ref graph_task() "graph" (selected at start-up)
 * - \ref terminal_task() "term."
 * - \ref about_task() "about"
 *
 * \param params Parameters for the task. (Not used.)
 */
static void main_task(void *params)
{
	bool graph_buffer_initialized = false;
	bool selection_changed = true;
	bool select_graph_buffer;
	enum menu_items current_selection = MENU_ITEM_GRAPH;
	gfx_coord_t x, y, display_y_offset;
	xTaskHandle temp_task_handle = NULL;

	for(;;) {
		// Show that task is executing
		oled1_set_led_state(&oled1, OLED1_LED3_ID, true);

		// Check buttons to see if user changed the selection
		if (oled1_get_button_state(&oled1, OLED1_BUTTON1_ID)
					&& (current_selection != MENU_ITEM_GRAPH)) {
			current_selection = MENU_ITEM_GRAPH;
			selection_changed = true;
		} 
		
		else if (oled1_get_button_state(&oled1, OLED1_BUTTON2_ID)
		&& (current_selection != NRF_ITEM)) 
		{
			current_selection = NRF_ITEM;
			selection_changed = true;
		}
		
		#if 0
		else if (oled1_get_button_state(&oled1, OLED1_BUTTON2_ID)
					&& (current_selection != MENU_ITEM_TERMINAL)) {
			current_selection = MENU_ITEM_TERMINAL;
			selection_changed = true;
		}
		#endif
		
		else if (oled1_get_button_state(&oled1, OLED1_BUTTON3_ID)
					&& (current_selection != MENU_ITEM_ABOUT)) {
			current_selection = MENU_ITEM_ABOUT;
			selection_changed = true;
		}

		// If selection changed, handle the selection
		if (selection_changed) {
			// Wait for and take the display semaphore before doing any changes.
			xSemaphoreTake(display_mutex, portMAX_DELAY);

			// We can now safely suspend the previously resumed task
			if (temp_task_handle) {
				vTaskSuspend(temp_task_handle);
				temp_task_handle = NULL;
			}

			// Select the new drawing task and corresponding display buffer
			switch (current_selection) {
			case MENU_ITEM_GRAPH:
				// Graph task runs continuously, no need to set task handle
				select_graph_buffer = true;
				break;
				
				
			#if 0
			case NRF_ITEM:
				//temp_task_handle = terminal_task_handle;
				temp_task_handle = nrf_task_handle;
				select_graph_buffer = false;
				break;	
			#endif
				
				
#if 1
			case MENU_ITEM_TERMINAL:
				temp_task_handle = terminal_task_handle;
				//temp_task_handle = nrf_task_handle;
				select_graph_buffer = false;
				break;
#endif

			default:
			case MENU_ITEM_ABOUT:
				temp_task_handle = about_task_handle;
				select_graph_buffer = false;
			}

			// Select and initialize display buffer to use.
			display_y_offset = select_graph_buffer ? CANVAS_GRAPH_Y_OFFSET : 0;

			// Draw the menu bar (only needs to be done once for graph)
			if (!select_graph_buffer || !graph_buffer_initialized) {
				// Clear the selected display buffer first
				gfx_mono_draw_filled_rect(0, display_y_offset,
						GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT / 2,
						GFX_PIXEL_CLR);

				// Draw menu lines, each item with height MENU_HEIGHT pixels
				y = display_y_offset + CANVAS_HEIGHT;
				gfx_mono_draw_horizontal_line(0, y, GFX_MONO_LCD_WIDTH,
						GFX_PIXEL_SET);

				x = MENU_ITEM_WIDTH;
				y++;

				for (uint8_t i = 0; i < (MENU_NUM_ITEMS - 1); i++) {
					gfx_mono_draw_vertical_line(x, y, MENU_HEIGHT,
							GFX_PIXEL_SET);
					x += 1 + MENU_ITEM_WIDTH;
				}

				// Highlight the current selection
				gfx_mono_draw_rect(current_selection * (1 + MENU_ITEM_WIDTH), y,
						MENU_ITEM_WIDTH, MENU_HEIGHT, GFX_PIXEL_SET);

				// Draw the menu item text
				x = (MENU_ITEM_WIDTH / 2) - ((5 * SYSFONT_WIDTH) / 2);
				y += (MENU_HEIGHT / 2) - (SYSFONT_HEIGHT / 2);

				for (uint8_t i = 0; i < MENU_NUM_ITEMS; i++) {
					gfx_mono_draw_string(menu_items_text[i], x, y, &sysfont);
					x += 1 + MENU_ITEM_WIDTH;
				}

				graph_buffer_initialized = true;
			}

			// Set display controller to output the new buffer
			ssd1306_set_display_start_line_address(display_y_offset);

			// We are done modifying the display, so give back the mutex
			xSemaphoreGive(display_mutex);

			selection_changed = false;

			// If a task handle was specified, resume it now
			if (temp_task_handle) {
				vTaskResume(temp_task_handle);
			}
		}

		// Show that task is done
		oled1_set_led_state(&oled1, OLED1_LED3_ID, false);

		vTaskDelay(MAIN_TASK_DELAY);
	}
}
portBASE_TYPE Init_EMAC(void)
{
portBASE_TYPE xReturn = pdPASS;

// Keil: function modified to access the EMAC
// Initializes the EMAC ethernet controller
  volatile unsigned int regv,tout,id1,id2;

  /* Enable P1 Ethernet Pins. */
  PINSEL2 = configPINSEL2_VALUE;
  PINSEL3 = (PINSEL3 & ~0x0000000F) | 0x00000005;

  /* Power Up the EMAC controller. */
  PCONP |= 0x40000000;
  vTaskDelay( 1 );

  /* Reset all EMAC internal modules. */
  MAC_MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
  MAC_COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES;

  /* A short delay after reset. */
  vTaskDelay( 1 );

  /* Initialize MAC control registers. */
  MAC_MAC1 = MAC1_PASS_ALL;
  MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
  MAC_MAXF = ETH_MAX_FLEN;
  MAC_CLRT = CLRT_DEF;
  MAC_IPGR = IPGR_DEF;

  /* Enable Reduced MII interface. */
  MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM;

  /* Reset Reduced MII Logic. */
  MAC_SUPP = SUPP_RES_RMII;
  MAC_SUPP = 0;

  /* Put the DP83848C in reset mode */
  write_PHY (PHY_REG_BMCR, 0x8000);
  write_PHY (PHY_REG_BMCR, 0x8000);

  /* Wait for hardware reset to end. */
  for (tout = 0; tout < 100; tout++) {
    vTaskDelay( 10 );
    regv = read_PHY (PHY_REG_BMCR);
    if (!(regv & 0x8000)) {
      /* Reset complete */
      break;
    }
  }

  /* Check if this is a DP83848C PHY. */
  id1 = read_PHY (PHY_REG_IDR1);
  id2 = read_PHY (PHY_REG_IDR2);
  if (((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID) {
    /* Configure the PHY device */

    /* Use autonegotiation about the link speed. */
    write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
    /* Wait to complete Auto_Negotiation. */
    for (tout = 0; tout < 10; tout++) {
      vTaskDelay( 100 );
      regv = read_PHY (PHY_REG_BMSR);
      if (regv & 0x0020) {
        /* Autonegotiation Complete. */
        break;
      }
    }
  }
  else
  {
    xReturn = pdFAIL;
  }

  /* Check the link status. */
  if( xReturn == pdPASS )
  {
    xReturn = pdFAIL;
    for (tout = 0; tout < 10; tout++) {
      vTaskDelay( 100 );
      regv = read_PHY (PHY_REG_STS);
      if (regv & 0x0001) {
        /* Link is on. */
        xReturn = pdPASS;
        break;
      }
    }
  }

  if( xReturn == pdPASS )
  {
    /* Configure Full/Half Duplex mode. */
    if (regv & 0x0004) {
      /* Full duplex is enabled. */
      MAC_MAC2    |= MAC2_FULL_DUP;
      MAC_COMMAND |= CR_FULL_DUP;
      MAC_IPGT     = IPGT_FULL_DUP;
    }
    else {
      /* Half duplex mode. */
      MAC_IPGT = IPGT_HALF_DUP;
    }

    /* Configure 100MBit/10MBit mode. */
    if (regv & 0x0002) {
      /* 10MBit mode. */
      MAC_SUPP = 0;
    }
    else {
      /* 100MBit mode. */
      MAC_SUPP = SUPP_SPEED;
    }

    /* Set the Ethernet MAC Address registers */
    MAC_SA0 = (emacETHADDR0 << 8) | emacETHADDR1;
    MAC_SA1 = (emacETHADDR2 << 8) | emacETHADDR3;
    MAC_SA2 = (emacETHADDR4 << 8) | emacETHADDR5;

    /* Initialize Tx and Rx DMA Descriptors */
    rx_descr_init ();
    tx_descr_init ();

    /* Receive Broadcast and Perfect Match Packets */
    MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;

    /* Create the semaphore used ot wake the uIP task. */
    vSemaphoreCreateBinary( xEMACSemaphore );

    /* Reset all interrupts */
    MAC_INTCLEAR  = 0xFFFF;

    /* Enable receive and transmit mode of MAC Ethernet core */
    MAC_COMMAND  |= (CR_RX_EN | CR_TX_EN);
    MAC_MAC1     |= MAC1_REC_EN;
  }

  return xReturn;
}
Exemple #4
0
/**
 * Function to set the SPI module.
 * \param obj - SPIContext pointer
 * \param options - SPI options
 * \param pin - SlaveSelect pin, use SPI_OPT_NO_SS if not necessary
 * \param speed - desired connection speed. System will automatically calculate the nearest possible speed
 * \return - 0 the operation is successful
 * \return - 1 the operation is failed. Check internal error for more details
 */
BOOL SPIConfig(SPIContext * obj, int options, int pin, long speed)
{
	double tout=0;
	obj->delay=100;
	obj->SPICON1=0;
	obj->SPICON2=0;
	obj->SPISTAT=0;
	obj->primary=0;
	obj->secondary=0;
	obj->ss_pin=0;
	obj->SPIIE=0;
	obj->SPFIE=0;
	obj->mode16 = FALSE;
	int index=0;
	#ifdef SPI_DBG_CFG
	uartwrite(1,"[SPI_DBG] Initiating configuration\n");
	#endif
	if(speed > _SPI_MAX_SPD)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] Speed too fast during config, quitting.\n");
		#endif
		_intSPIerr = SpdTooFast;
		return 1;
	}
	unsigned int divider = (unsigned int)ceil(16000000.0/(double)speed);
	#ifdef SPI_DBG_CFG
	sprintf(spi_dbg_msg,"[SPI_DBG] Calculated divider: %d\n",divider);
	UARTWrite(1,spi_dbg_msg);	
	#endif
	index = _spi_find_divider_index(divider);
	obj->primary = _spi_divider_primary[index];
	obj->secondary = _spi_divider_secondary[index];
	obj->ss_pin = pin;
	#ifdef SPI_DBG_CFG
	sprintf(spi_dbg_msg,"[SPI_DBG] primary %d\n[SPI_DBG] secondary %d\n",_spi_divider_primary_value[obj->primary],_spi_divider_secondary_value[obj->secondary]);
	uartwrite(1,spi_dbg_msg);
	#endif	
	tout = ((float)_spi_divider_primary_value[obj->primary] * (float)_spi_divider_secondary_value[obj->secondary])/16; // time (in us) per bit shifted out
	if (options & SPI_OPT_MODE16)
	{
		obj->mode16 = TRUE;
		obj->SPICON1 |= SPI_MSK_MODE16;
		obj->delay = ceil(32*tout/10);
	}
	else
		obj->delay = ceil(16*tout/10);
	if (obj->delay < 1)
		obj->delay = 1;
	#ifdef SPI_DBG_CFG
	sprintf(spi_dbg_msg,"[SPI_DBG] Requested speed %.2f KHz\n[SPI_DBG] Nearest speed %.2f KHz\n",(double)speed/1000,1000/tout);
	uartwrite(1,spi_dbg_msg);
	#endif	
	if((options & SPI_OPT_MODE_0) || (!(options & (SPI_OPT_MODE_0 | SPI_OPT_MODE_1 | SPI_OPT_MODE_2 | SPI_OPT_MODE_3))))
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] Selecting MODE 0\n");
		#endif
		obj->SPICON1 |= SPI_MSK_CPHA; //288 //  bit5=1 master mode + bit8=1 data changes on clock trailing edge
		obj->SPICON1 &= ~SPI_MSK_CPOL;
	}
	
	if(options & SPI_OPT_MODE_1)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] Selecting MODE 1\n");
		#endif
		obj->SPICON1 &= ~SPI_MSK_CPHA;
 		obj->SPICON1 &= ~SPI_MSK_CPOL; //32// bit5=1 master mode
	}
	
	if(options & SPI_OPT_MODE_2)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] Selecting MODE 2\n");
		#endif
		obj->SPICON1 |= SPI_MSK_CPHA | SPI_MSK_CPOL; //352 // bit5=1 master mode + bit8=1 data changes on clock trailing edge + bit6=1 clock polarity reversed
	}
		
	if(options & SPI_OPT_MODE_3)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] Selecting MODE 3\n");
		#endif
		obj->SPICON1 |= SPI_MSK_CPOL;
		obj->SPICON1 &= ~SPI_MSK_CPHA; //96 // bit5=1 master mode + bit6=1 clock polarity
	}
	
	obj->SPICON1 |= obj->primary&0b00000011;
	obj->SPICON1 |= (obj->secondary&0b00011100)<<2;
	if(options & SPI_OPT_MASTER)
		obj->SPICON1 |=  SPI_MSK_MASTER;
	if(options & SPI_OPT_SLAVE)
		obj->SPICON1 &=  ~SPI_MSK_MASTER; //0b1111111111011111;
		
	if(options & SPI_OPT_SLAVE_SELECT)
		obj->SPICON1 |= SPI_MSK_SSEN;
	
	if ((options & (SPI_OPT_SLAVE | SPI_OPT_MASTER)) == 0)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] No mode (Master/Slave) selected, quitting\n");
		#endif
		_intSPIerr=NoModeSpecified;
		obj->SPICON1=0;
		obj->SPICON2=0;
		obj->SPISTAT=0;
		obj->primary=0;
		obj->secondary=0;
		obj->ss_pin=0;
		return 1;
	}
	/*#if(GroveNest == Board)
	obj->SPICON1 |= 0b1000000;
	#endif*/

	obj->SPISTAT = 0x00;
	obj->SPICON2 = 0x00;
	obj->SPIIE = 0;
	obj->SPFIE = 0;
	obj->IP = 1;
	obj->FIP = 1;
	#ifndef SPI2_FLASH
	if(pin != SPI_OPT_NO_SS)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] SS pin selected, configuring\n");
		#endif
		obj->ss_pin = pin;
		IOInit(pin,out);
		vTaskDelay(1);
		IOPut(pin,on);
		#ifdef SPI_DBG_CFG
		sprintf(spi_dbg_msg,"[SPI_DBG] SS us of delay %u\n",obj->delay*10);
		UARTWrite(1,spi_dbg_msg);
		#endif
	}
	else
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] SS pin cleared, not using\n");
		#endif
		obj->ss_pin=SPI_OPT_NO_SS;
	}
	#else
	TRISDbits.TRISD6=0;
	#endif
	if(options & SPI_OPT_DI_SAMPLE_END)
	{
		#ifdef SPI_DBG_CFG
		uartwrite(1,"[SPI_DBG] DI sample set to end of DO clock time\n");
		#endif
		obj->SPICON1 |= 0b1000000000;
	}
	_intSPIerr=SPI_NO_ERR;
	return 0;
}
Exemple #5
0
void vuIP_Task( void *pvParameters )
{
portBASE_TYPE i;
unsigned long ulNewEvent = 0UL;
unsigned long ulUIP_Events = 0UL;

	( void ) pvParameters;

	/* Initialise the uIP stack. */
	prvInitialise_uIP();

	/* Initialise the MAC. */
	vInitEmac();

	while( lEMACWaitForLink() != pdPASS )
    {
        vTaskDelay( uipINIT_WAIT );
    }

	for( ;; )
	{
		if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL )
		{
			/* Is there received data ready to be processed? */
			uip_len = ( unsigned short ) ulEMACRead();

			if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
			{
				/* Standard uIP loop taken from the uIP manual. */
				if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
				{
					uip_arp_ipin();
					uip_input();

					/* If the above function invocation resulted in data that
					should be sent out on the network, the global variable
					uip_len is set to a value > 0. */
					if( uip_len > 0 )
					{
						uip_arp_out();
						vEMACWrite();
					}
				}
				else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
				{
					uip_arp_arpin();

					/* If the above function invocation resulted in data that
					should be sent out on the network, the global variable
					uip_len is set to a value > 0. */
					if( uip_len > 0 )
					{
						vEMACWrite();
					}
				}
			}
			else
			{
				ulUIP_Events &= ~uipETHERNET_RX_EVENT;
			}
		}

		if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )
		{
			ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;

			for( i = 0; i < UIP_CONNS; i++ )
			{
				uip_periodic( i );

				/* If the above function invocation resulted in data that
				should be sent out on the network, the global variable
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					uip_arp_out();
					vEMACWrite();
				}
			}
		}

		/* Call the ARP timer function every 10 seconds. */
		if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
		{
			ulUIP_Events &= ~uipARP_TIMER_EVENT;
			uip_arp_timer();
		}

		if( ulUIP_Events == pdFALSE )
		{
			xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
			ulUIP_Events |= ulNewEvent;
		}
	}
}
Exemple #6
0
void vuIP_Task( void *pvParameters )
{
portBASE_TYPE i;
uip_ipaddr_t xIPAddr;
struct timer periodic_timer, arp_timer;
extern void ( vEMAC_ISR_Wrapper )( void );

	vtWebServerStruct *param = (vtWebServerStruct *)pvParameters;
	roverStatusDev = param->roverStatusDev;
	lcdDev = param->lcdDev;
	mapDev = param->mapDev;

	/* Initialise the uIP stack. */
	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );
	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );
	uip_init();
	uip_ipaddr( xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
	uip_sethostaddr( xIPAddr );
	uip_ipaddr( xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
	uip_setnetmask( xIPAddr );
	httpd_init();

	/* Create the semaphore used to wake the uIP task. */
	vSemaphoreCreateBinary( xEMACSemaphore );

	/* Initialise the MAC. */
	while( lEMACInit() != pdPASS )
    {
        vTaskDelay( uipINIT_WAIT );
    }

	portENTER_CRITICAL();
	{
		EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );

		/* Set the interrupt priority to the max permissible to cause some
		interrupt nesting. */
		NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY );

		/* Enable the interrupt. */
		NVIC_EnableIRQ( ENET_IRQn );
		prvSetMACAddress();
	}
	portEXIT_CRITICAL();


	for( ;; )
	{
		/* Is there received data ready to be processed? */
		uip_len = ulGetEMACRxData();

		if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
		{
			/* Standard uIP loop taken from the uIP manual. */
			if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
			{
				uip_arp_ipin();
				uip_input();

				/* If the above function invocation resulted in data that
				should be sent out on the network, the global variable
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					uip_arp_out();
					vSendEMACTxData( uip_len );
				}
			}
			else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
			{
				uip_arp_arpin();

				/* If the above function invocation resulted in data that
				should be sent out on the network, the global variable
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					vSendEMACTxData( uip_len );
				}
			}
		}
		else
		{
			if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) )
			{
				timer_reset( &periodic_timer );
				for( i = 0; i < UIP_CONNS; i++ )
				{
					uip_periodic( i );

					/* If the above function invocation resulted in data that
					should be sent out on the network, the global variable
					uip_len is set to a value > 0. */
					if( uip_len > 0 )
					{
						uip_arp_out();
						vSendEMACTxData( uip_len );
					}
				}

				/* Call the ARP timer function every 10 seconds. */
				if( timer_expired( &arp_timer ) )
				{
					timer_reset( &arp_timer );
					uip_arp_timer();
				}
			}
			else
			{
				/* We did not receive a packet, and there was no periodic
				processing to perform.  Block for a fixed period.  If a packet
				is received during this period we will be woken by the ISR
				giving us the Semaphore. */
				xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );
			}
		}
	}
}
Exemple #7
0
void starting_delay( unsigned long ul )
{
	vTaskDelay( ( portTickType ) ul );
}
Exemple #8
0
static void prvRecursiveMutexControllingTask( void *pvParameters )
{
unsigned portBASE_TYPE ux;

	/* Just to remove compiler warning. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Should not be able to 'give' the mutex, as we have not yet 'taken'
		it.   The first time through, the mutex will not have been used yet,
		subsequent times through, at this point the mutex will be held by the
		polling task. */
		if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
		{
			xErrorOccurred = pdTRUE;
		}

		for( ux = 0; ux < recmuMAX_COUNT; ux++ )
		{
			/* We should now be able to take the mutex as many times as
			we like.
			
			The first time through the mutex will be immediately available, on
			subsequent times through the mutex will be held by the polling task
			at this point and this Take will cause the polling task to inherit
			the priority of this task.  In this case the block time must be
			long enough to ensure the polling task will execute again before the
			block time expires.  If the block time does expire then the error
			flag will be set here. */
			if( xSemaphoreTakeRecursive( xMutex, recmuFIVE_TICK_DELAY ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			/* Ensure the other task attempting to access the mutex (and the
			other demo tasks) are able to execute to ensure they either block
			(where a block time is specified) or return an error (where no 
			block time is specified) as the mutex is held by this task. */
			vTaskDelay( recmuSHORT_DELAY );
		}

		/* For each time we took the mutex, give it back. */
		for( ux = 0; ux < recmuMAX_COUNT; ux++ )
		{
			/* Ensure the other task attempting to access the mutex (and the
			other demo tasks) are able to execute. */
			vTaskDelay( recmuSHORT_DELAY );

			/* We should now be able to give the mutex as many times as we
			took it.  When the mutex is available again the Blocking task
			should be unblocked but not run because it has a lower priority
			than this task.  The polling task should also not run at this point
			as it too has a lower priority than this task. */
			if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}
		}

		/* Having given it back the same number of times as it was taken, we
		should no longer be the mutex owner, so the next give should fail. */
		if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
		{
			xErrorOccurred = pdTRUE;
		}

		/* Keep count of the number of cycles this task has performed so a 
		stall can be detected. */
		uxControllingCycles++;

		/* Suspend ourselves so the blocking task can execute. */
		xControllingIsSuspended = pdTRUE;
		vTaskSuspend( NULL );
		xControllingIsSuspended = pdFALSE;
	}
}
Exemple #9
0
/**
 * @brief	The main task for the LCD
 * @param	pvParameters:
 * @retval	None
 */
void lcdTask(void *pvParameters)
{
    /* Initialize the hardware */
    prvHardwareInit();

    /* Display splash screen */
    prvSplashScreen();

    /* Make sure all channels have started up before we initialize the GUI */
    while (!prvAllChanneAreDoneInitializing())
    {
        vTaskDelay(1 / portTICK_PERIOD_MS);
    }

    /* Initialize the GUI elements */
    prvInitGuiElements();

    xLCDEventQueue = xQueueCreate(10, sizeof(LCDEventMessage));
    if (xLCDEventQueue == 0)
    {
        // Queue was not created and must not be used.
    }

    prvMainTextBoxRefreshTimer = xTimerCreate("MainTextBoxTimer", 10 / portTICK_PERIOD_MS, pdTRUE, 0, prvMainContainerRefreshTimerCallback);
    if (prvMainTextBoxRefreshTimer != NULL)
        xTimerStart(prvMainTextBoxRefreshTimer, portMAX_DELAY);

    LCDEventMessage receivedMessage;

//	GUITextBox_WriteString(GUITextBoxId_Clock, "14:15:12");

    /* The parameter in vTaskDelayUntil is the absolute time
     * in ticks at which you want to be woken calculated as
     * an increment from the time you were last woken. */
    TickType_t xNextWakeTime;
    /* Initialize xNextWakeTime - this only needs to be done once. */
    xNextWakeTime = xTaskGetTickCount();
    while (1)
    {
        /* Wait for a message to be received or the timeout to happen */
        if (xQueueReceive(xLCDEventQueue, &receivedMessage, 50) == pdTRUE)
        {
            /* Item successfully removed from the queue */
            switch (receivedMessage.event)
            {
            /* New touch data received */
            case LCDEvent_TouchEvent:
                if (receivedMessage.data[3] == FT5206Point_1)
                {
#if 0
                    /* DEBUG */
                    if (GUI_GetDisplayStateForTextBox(GUITextBoxId_Debug) == GUIDisplayState_NotHidden)
                    {
                        GUITextBox_SetWritePosition(GUITextBoxId_Debug, 5, 5);
                        GUITextBox_Clear(GUITextBoxId_Debug);
                        GUITextBox_WriteString(GUITextBoxId_Debug, "X:");
                        GUITextBox_WriteNumber(GUITextBoxId_Debug, receivedMessage.data[0]);
                        GUITextBox_WriteString(GUITextBoxId_Debug, ", Y:");
                        GUITextBox_WriteNumber(GUITextBoxId_Debug, receivedMessage.data[1]);
                        GUITextBox_WriteString(GUITextBoxId_Debug, ", EVENT:");
                        GUITextBox_WriteNumber(GUITextBoxId_Debug, receivedMessage.data[2]);
                    }
#endif

#if 0
                    /* Draw a dot on debug */
                    if (!prvDebugConsoleIsHidden)
                    {
                        LCD_SetForegroundColor(LCD_COLOR_GREEN);
                        LCD_DrawCircle(receivedMessage.data[0], receivedMessage.data[1], 2, 1);
                    }
#endif

                    GUITouchEvent touchEvent;
                    if (receivedMessage.data[2] == FT5206Event_PutUp)
                        touchEvent = GUITouchEvent_Up;
                    else if (receivedMessage.data[2] == FT5206Event_PutDown)
                        touchEvent = GUITouchEvent_Down;
                    /* Check all buttons */
                    GUIButton_CheckAllActiveForTouchEventAt(touchEvent, receivedMessage.data[0], receivedMessage.data[1]);
                    /* Check all text boxes */
                    GUITextBox_CheckAllActiveForTouchEventAt(touchEvent, receivedMessage.data[0], receivedMessage.data[1]);
                    /* Check all containers */
                    GUIContainer_CheckAllActiveForTouchEventAt(touchEvent, receivedMessage.data[0], receivedMessage.data[1]);
                }
                break;

            /* New temperature data received */
            case LCDEvent_TemperatureData:
                memcpy(&prvTemperature, receivedMessage.data, sizeof(float));
                int8_t currentTemp = (int8_t)prvTemperature - 11;
                GUITextBox_Draw(GUITextBoxId_Temperature);
                GUITextBox_SetWritePosition(GUITextBoxId_Temperature, 50, 3);
                GUITextBox_WriteNumber(GUITextBoxId_Temperature, (int32_t)currentTemp);
                GUITextBox_WriteString(GUITextBoxId_Temperature, " C");
                break;

            /* Debug message received */
            case LCDEvent_DebugMessage:
                GUITextBox_SetWritePosition(GUITextBoxId_Debug, 5, 5);
                GUITextBox_Clear(GUITextBoxId_Debug);
                GUITextBox_WriteNumber(GUITextBoxId_Debug, receivedMessage.data[0]);
                GUITextBox_WriteString(GUITextBoxId_Debug, " - ");
                GUITextBox_WriteString(GUITextBoxId_Debug, (uint8_t*)receivedMessage.data[1]);
                break;


            default:
                break;
            }
        }
        else
        {
            /* Timeout has occured i.e. no message available */
//			HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
            /* Do something else */
        }
    }
}
Exemple #10
0
void network_thread(void *p)
{
    struct netif *netif;
    struct ip_addr ipaddr, netmask, gw;
#if LWIP_DHCP==1
    int mscnt = 0;
#endif
    /* the mac address of the board. this should be unique per board */
    unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

    netif = &server_netif;

#if LWIP_DHCP==0
    /* initliaze IP addresses to be used */
    IP4_ADDR(&ipaddr,  192, 168,   1, 10);
    IP4_ADDR(&netmask, 255, 255, 255,  0);
    IP4_ADDR(&gw,      192, 168,   1,  1);
#endif

    /* print out IP settings of the board */
    print("\r\n\r\n");
    print("-----lwIP Socket Mode Demo Application ------\r\n");

#if LWIP_DHCP==0
    print_ip_settings(&ipaddr, &netmask, &gw);
    /* print all application headers */
#endif

#if LWIP_DHCP==1
	ipaddr.addr = 0;
	gw.addr = 0;
	netmask.addr = 0;
#endif
    /* Add network interface to the netif_list, and set it as default */
    if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
        xil_printf("Error adding N/W interface\r\n");
        return;
    }
    netif_set_default(netif);

    /* specify that the network if is up */
    netif_set_up(netif);

    /* start packet receive thread - required for lwIP operation */
    sys_thread_new("xemacif_input_thread", (void(*)(void*))xemacif_input_thread, netif,
            THREAD_STACKSIZE,
            DEFAULT_THREAD_PRIO);

#if LWIP_DHCP==1
    dhcp_start(netif);
    while (1) {
#ifdef OS_IS_FREERTOS
		vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
#else
		sleep(DHCP_FINE_TIMER_MSECS);
#endif
		dhcp_fine_tmr();
		mscnt += DHCP_FINE_TIMER_MSECS;
		if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
			dhcp_coarse_tmr();
			mscnt = 0;
		}
	}
#else
    print_headers();
    launch_app_threads();
#ifdef OS_IS_FREERTOS
    vTaskDelete(NULL);
#endif
#endif
    return;
}
Exemple #11
0
/*
 * Controller task as described above.
 */
static portTASK_FUNCTION( vCounterControlTask, pvParameters )
{
uint32_t ulLastCounter;
short sLoops;
short sError = pdFALSE;

	/* Just to stop warning messages. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Start with the counter at zero. */
		ulCounter = ( uint32_t ) 0;

		/* First section : */

		/* Check the continuous count task is running. */
		for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
		{
			/* Suspend the continuous count task so we can take a mirror of the
			shared variable without risk of corruption.  This is not really
			needed as the other task raises its priority above this task's
			priority. */
			vTaskSuspend( xContinuousIncrementHandle );
			{
				#if( INCLUDE_eTaskGetState == 1 )
				{
					configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended );
				}
				#endif /* INCLUDE_eTaskGetState */

				ulLastCounter = ulCounter;
			}
			vTaskResume( xContinuousIncrementHandle );

			#if( configUSE_PREEMPTION == 0 )
				taskYIELD();
			#endif

			#if( INCLUDE_eTaskGetState == 1 )
			{
				configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady );
			}
			#endif /* INCLUDE_eTaskGetState */

			/* Now delay to ensure the other task has processor time. */
			vTaskDelay( priSLEEP_TIME );

			/* Check the shared variable again.  This time to ensure mutual
			exclusion the whole scheduler will be locked.  This is just for
			demo purposes! */
			vTaskSuspendAll();
			{
				if( ulLastCounter == ulCounter )
				{
					/* The shared variable has not changed.  There is a problem
					with the continuous count task so flag an error. */
					sError = pdTRUE;
				}
			}
			xTaskResumeAll();
		}

		/* Second section: */

		/* Suspend the continuous counter task so it stops accessing the shared
		variable. */
		vTaskSuspend( xContinuousIncrementHandle );

		/* Reset the variable. */
		ulCounter = ( uint32_t ) 0;

		#if( INCLUDE_eTaskGetState == 1 )
		{
			configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
		}
		#endif /* INCLUDE_eTaskGetState */

		/* Resume the limited count task which has a higher priority than us.
		We should therefore not return from this call until the limited count
		task has suspended itself with a known value in the counter variable. */
		vTaskResume( xLimitedIncrementHandle );

		#if( configUSE_PREEMPTION == 0 )
			taskYIELD();
		#endif

		/* This task should not run again until xLimitedIncrementHandle has
		suspended itself. */
		#if( INCLUDE_eTaskGetState == 1 )
		{
			configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
		}
		#endif /* INCLUDE_eTaskGetState */

		/* Does the counter variable have the expected value? */
		if( ulCounter != priMAX_COUNT )
		{
			sError = pdTRUE;
		}

		if( sError == pdFALSE )
		{
			/* If no errors have occurred then increment the check variable. */
			portENTER_CRITICAL();
				usCheckVariable++;
			portEXIT_CRITICAL();
		}

		/* Resume the continuous count task and do it all again. */
		vTaskResume( xContinuousIncrementHandle );

		#if( configUSE_PREEMPTION == 0 )
			taskYIELD();
		#endif
	}
}
void vuIP_Task( void *pvParameters )
{
portBASE_TYPE i;
uip_ipaddr_t xIPAddr;
struct timer periodic_timer, arp_timer;
extern void ( vEMAC_ISR_Wrapper )( void );

	/* Create the semaphore used by the ISR to wake this task. */
	vSemaphoreCreateBinary( xEMACSemaphore );
	
	/* Initialise the uIP stack. */
	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );
	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );
	uip_init();
	uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );
	uip_sethostaddr( xIPAddr );
	httpd_init();

	/* Initialise the MAC. */
	while( Init_EMAC() != pdPASS )
    {
        vTaskDelay( uipINIT_WAIT );
    }

	portENTER_CRITICAL();
	{
		MAC_INTENABLE = INT_RX_DONE;
        VICIntEnable |= 0x00200000;
        VICVectAddr21 = ( portLONG ) vEMAC_ISR_Wrapper;
		prvSetMACAddress();
	}
	portEXIT_CRITICAL();
	

	for( ;; )
	{
		/* Is there received data ready to be processed? */
		uip_len = uiGetEMACRxData( uip_buf );
		
		if( uip_len > 0 )
		{
			/* Standard uIP loop taken from the uIP manual. */
			if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
			{
				uip_arp_ipin();
				uip_input();

				/* If the above function invocation resulted in data that 
				should be sent out on the network, the global variable 
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					uip_arp_out();
					prvENET_Send();
				}
			}
			else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
			{
				uip_arp_arpin();

				/* If the above function invocation resulted in data that 
				should be sent out on the network, the global variable 
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					prvENET_Send();
				}
			}
		}
		else
		{
			if( timer_expired( &periodic_timer ) )
			{
				timer_reset( &periodic_timer );
				for( i = 0; i < UIP_CONNS; i++ )
				{
					uip_periodic( i );
	
					/* If the above function invocation resulted in data that 
					should be sent out on the network, the global variable 
					uip_len is set to a value > 0. */
					if( uip_len > 0 )
					{
						uip_arp_out();
						prvENET_Send();
					}
				}	
	
				/* Call the ARP timer function every 10 seconds. */
				if( timer_expired( &arp_timer ) )
				{
					timer_reset( &arp_timer );
					uip_arp_timer();
				}
			}
			else
			{			
				/* We did not receive a packet, and there was no periodic
				processing to perform.  Block for a fixed period.  If a packet
				is received during this period we will be woken by the ISR
				giving us the Semaphore. */
				xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );			
			}
		}
	}
}
void prvLCDTask( void * pvParameters )
{
unsigned portBASE_TYPE uxIndex;
QueueHandle_t *pxLCDQueue;
xLCDMessage xReceivedMessage;
char *pcString;
const unsigned char ucCFGData[] = {	
											0x30,   /* Set data bus to 8-bits. */
											0x30,
											0x30,
											0x3C,   /* Number of lines/font. */
											0x08,   /* Display off. */
											0x01,   /* Display clear. */
											0x06,   /* Entry mode [cursor dir][shift]. */
											0x0C	/* Display on [display on][curson on][blinking on]. */
									  };  

	/* To test the parameter passing mechanism, the queue on which messages are
	received is passed in as a parameter even though it is available as a file
	scope variable anyway. */
	pxLCDQueue = ( QueueHandle_t * ) pvParameters;

	/* Configure the LCD. */
	uxIndex = 0;
	while( uxIndex < sizeof( ucCFGData ) )
	{
		prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
		uxIndex++;
		vTaskDelay( mainCHAR_WRITE_DELAY );
	}

	/* Turn the LCD Backlight on. */
	prvPDCWrite( PDC_CSR, 0x01 );

	/* Clear display. */
	vTaskDelay( mainCHAR_WRITE_DELAY );
	prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR ); 

	uxIndex = 0;
	for( ;; )    
	{
		/* Wait for a message to arrive. */
		if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) )
		{
			/* Which row does the received message say to write to? */
			PDCLCDSetPos( 0, xReceivedMessage.xRow );

			/* Where is the string we are going to display? */
			pcString = *xReceivedMessage.ppcMessageToDisplay;
			
			while( *pcString )
			{
				/* Don't write out the string too quickly as LCD's are usually 
				pretty slow devices. */
				vTaskDelay( mainCHAR_WRITE_DELAY );
				prvPDCWrite( PDC_LCD_RAM, *pcString );
				pcString++;
			}		
		}
	}
}
void XMLRPCServer::UDPreceive(void* params)
{
    struct netconn *conn;
    struct netbuf *buf;
    err_t err;

    // Initialize memory (in stack) for message.
    char message[60]; // TODO: Set its size according to UDPMessage.
    os_printf("Test!\n");
    conn = netconn_new(NETCONN_UDP);
    for (;;) {
        // Check if connection was created successfully.
        if (conn != NULL) {
            err = netconn_bind(conn, IP_ADDR_ANY, UDP_RECEIVE_PORT);

            // Check if we were able to bind to port.
            if (err == ERR_OK) {
                portTickType xLastWakeTime;
                // Initialize the xLastWakeTime variable with the current time.
                xLastWakeTime = xTaskGetTickCount();

                // Start periodic loop.
                while (1) {
                    buf = netconn_recv(conn);
                    if (buf != NULL) {
                        struct ip_addr* ip;
                        uint16_t port;
                        ip = buf->addr;
                        port = buf->port;
                        //if(ip != NULL)
                        //os_printf("Received from %d:%d!\n", ip->addr, port);
                        // Copy received data into message.
                        uint16_t len = netbuf_len(buf);
                        if (len > 15) {
                            netbuf_copy (buf, &message, len);
                            uint32_t connectionID = *((uint32_t*)&message[0]);
                            TopicReader* tr = getTopicReader(connectionID);
                            if (tr != NULL) {
                                tr->enqueueMessage(&message[8]);
                                //os_printf("ConnectionID: %d, topic:%s\n", connectionID, tr->getTopic());
                            }
                        }
                        // Deallocate previously created memory.
                        netbuf_delete(buf);
                    }
                    // Use delay until to guarantee periodic execution of each loop iteration.
                    else {
                        os_printf("buf = NULL!\n");
                        vTaskDelayUntil(&xLastWakeTime, 30);
                    }
                }
            } else {
                os_printf("cannot bind netconn\n");
            }
        } else {
            os_printf("cannot create new UDP netconn\n");
            conn = netconn_new(NETCONN_UDP);
        }
        // If connection failed, wait for 50 ms before retrying.
        vTaskDelay(50);
    }
}
Exemple #15
0
void vuIP_Task( void *pvParameters )
{
portBASE_TYPE i;
uip_ipaddr_t xIPAddr;
struct timer periodic_timer, arp_timer;
extern void ( vEMAC_ISR_Wrapper )( void );

	( void ) pvParameters;

	/* Initialise the uIP stack. */
	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );
	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );
	uip_init();
	uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
	uip_sethostaddr( &xIPAddr );
	uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
	uip_setnetmask( &xIPAddr );
	prvSetMACAddress();
	httpd_init();

	/* Create the semaphore used to wake the uIP task. */
	vSemaphoreCreateBinary( xEMACSemaphore );

	/* Initialise the MAC. */
	vInitEmac();

	while( lEMACWaitForLink() != pdPASS )
    {
        vTaskDelay( uipINIT_WAIT );
    }

	for( ;; )
	{
		/* Is there received data ready to be processed? */
		uip_len = ( unsigned short ) ulEMACRead();
		
		if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
		{
			/* Standard uIP loop taken from the uIP manual. */
			if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
			{
				uip_arp_ipin();
				uip_input();

				/* If the above function invocation resulted in data that
				should be sent out on the network, the global variable
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					uip_arp_out();
					vEMACWrite();
				}
			}
			else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
			{
				uip_arp_arpin();

				/* If the above function invocation resulted in data that
				should be sent out on the network, the global variable
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					vEMACWrite();
				}
			}
		}
		else
		{
			if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) )
			{
				timer_reset( &periodic_timer );
				for( i = 0; i < UIP_CONNS; i++ )
				{
					uip_periodic( i );

					/* If the above function invocation resulted in data that
					should be sent out on the network, the global variable
					uip_len is set to a value > 0. */
					if( uip_len > 0 )
					{
						uip_arp_out();
						vEMACWrite();
					}
				}

				/* Call the ARP timer function every 10 seconds. */
				if( timer_expired( &arp_timer ) )
				{
					timer_reset( &arp_timer );
					uip_arp_timer();
				}
			}
			else
			{
				/* We did not receive a packet, and there was no periodic
				processing to perform.  Block for a fixed period.  If a packet
				is received during this period we will be woken by the ISR
				giving us the Semaphore. */
				xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );
			}
		}
	}
}
Exemple #16
0
/* See the header file for descriptions of public functions. */
long lEMACSend( char *pcFrom, unsigned long ulLength, long lEndOfFrame )
{
static unsigned portBASE_TYPE uxTxBufferIndex = 0;
portBASE_TYPE xWaitCycles = 0;
long lReturn = pdPASS;
char *pcBuffer;
unsigned long ulLastBuffer, ulDataBuffered = 0, ulDataRemainingToSend, ulLengthToSend;

	/* If the length of data to be transmitted is greater than each individual
	transmit buffer then the data will be split into more than one buffer.
	Loop until the entire length has been buffered. */
	while( ulDataBuffered < ulLength )
	{
		/* Is a buffer available? */
		while( !( xTxDescriptors[ uxTxBufferIndex ].U_Status.status & AT91C_TRANSMIT_OK ) )
		{
			/* There is no room to write the Tx data to the Tx buffer.  Wait a
			short while, then try again. */
			xWaitCycles++;
			if( xWaitCycles > emacMAX_WAIT_CYCLES )
			{
				/* Give up. */
				lReturn = pdFAIL;
				break;
			}
			else
			{
				vTaskDelay( emacBUFFER_WAIT_DELAY );
			}
		}
	
		/* lReturn will only be pdPASS if a buffer is available. */
		if( lReturn == pdPASS )
		{
			portENTER_CRITICAL();
			{
				/* Get the address of the buffer from the descriptor, then copy 
				the data into the buffer. */
				pcBuffer = ( char * ) xTxDescriptors[ uxTxBufferIndex ].addr;

				/* How much can we write to the buffer? */
				ulDataRemainingToSend = ulLength - ulDataBuffered;
				if( ulDataRemainingToSend <= ETH_TX_BUFFER_SIZE )
				{
					/* We can write all the remaining bytes. */
					ulLengthToSend = ulDataRemainingToSend;
				}
				else
				{
					/* We can not write more than ETH_TX_BUFFER_SIZE in one go. */
					ulLengthToSend = ETH_TX_BUFFER_SIZE;
				}

				/* Copy the data into the buffer. */
				memcpy( ( void * ) pcBuffer, ( void * ) &( pcFrom[ ulDataBuffered ] ), ulLengthToSend );
				ulDataBuffered += ulLengthToSend;

				/* Is this the last data for the frame? */
				if( lEndOfFrame && ( ulDataBuffered >= ulLength ) )
				{
					/* No more data remains for this frame so we can start the 
					transmission. */
					ulLastBuffer = AT91C_LAST_BUFFER;
				}
				else
				{
					/* More data to come for this frame. */
					ulLastBuffer = 0;
				}
	
				/* Fill out the necessary in the descriptor to get the data sent, 
				then move to the next descriptor, wrapping if necessary. */
				if( uxTxBufferIndex >= ( NB_TX_BUFFERS - 1 ) )
				{				
					xTxDescriptors[ uxTxBufferIndex ].U_Status.status = 	( ulLengthToSend & ( unsigned long ) AT91C_LENGTH_FRAME )
																			| ulLastBuffer
																			| AT91C_TRANSMIT_WRAP;
					uxTxBufferIndex = 0;
				}
				else
				{
					xTxDescriptors[ uxTxBufferIndex ].U_Status.status = 	( ulLengthToSend & ( unsigned long ) AT91C_LENGTH_FRAME )
																			| ulLastBuffer;
					uxTxBufferIndex++;
				}
	
				/* If this is the last buffer to be sent for this frame we can
				start the transmission. */
				if( ulLastBuffer )
				{
					AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
				}
			}
			portEXIT_CRITICAL();
		}
		else
		{
			break;
		}
	}

	return lReturn;
}
Exemple #17
0
static void prvLCDTask( void *pvParameters )
{
xQueueMessage xReceivedMessage;

/* Buffer into which strings are formatted and placed ready for display on the
LCD.  Note this is a static variable to prevent it being allocated on the task
stack, which is too small to hold such a variable.  The stack size is configured
when the task is created. */
static char cBuffer[ 50 ];
unsigned char ucLine = 1;

	/* Now the scheduler has been started (it must have been for this task to
	be running), start the check timer too.  The call to xTimerStart() will
	block until the command has been accepted. */
	if( xCheckTimer != NULL )
	{
		xTimerStart( xCheckTimer, portMAX_DELAY );
	}

	/* This is the only function that is permitted to access the LCD.
	
	First print out the number of bytes that remain in the FreeRTOS heap.  This
	is done after a short delay to ensure all the demo tasks have created all
	the objects they are going to use.  */
	vTaskDelay( mainTIMER_TEST_PERIOD * 10 );
	sprintf( cBuffer, "%d heap free", ( int ) xPortGetFreeHeapSize() );
	halLcdPrintLine( cBuffer, ucLine, OVERWRITE_TEXT );
	ucLine++;
	
	/* Just as a test of the port, and for no functional reason, check the task
	parameter contains its expected value. */
	if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )
	{
		halLcdPrintLine( "Invalid parameter", ucLine, OVERWRITE_TEXT );
		ucLine++;		
	}

	for( ;; )
	{
		/* Wait for a message to be received.  Using portMAX_DELAY as the block
		time will result in an indefinite wait provided INCLUDE_vTaskSuspend is
		set to 1 in FreeRTOSConfig.h, therefore there is no need to check the
		function return value and the function will only return when a value
		has been received. */
		xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );

		/* Clear the LCD if no room remains for any more text output. */
		if( ucLine > mainMAX_LCD_LINES )
		{
			halLcdClearScreen();
			ucLine = 0;
		}
		
		/* What is this message?  What does it contain? */
		switch( xReceivedMessage.cMessageID )
		{
			case mainMESSAGE_BUTTON_UP		:	/* The button poll task has just
												informed this task that the up
												button on the joystick input has
												been pressed or released. */
												sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue );
												break;

			case mainMESSAGE_BUTTON_SEL		:	/* The select button interrupt
												just informed this task that the
												select button has been pressed.
												In this case the pointer to the 
												string to print is sent directly 
												in the ulMessageValue member of 
												the	message.  This just 
												demonstrates a different 
												communication technique. */
												sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );
												break;
												
			case mainMESSAGE_STATUS			:	/* The tick interrupt hook
												function has just informed this
												task of the system status.
												Generate a string in accordance
												with the status value. */
												prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue );
												break;
												
			default							:	sprintf( cBuffer, "Unknown message" );
												break;
		}
		
		/* Output the message that was placed into the cBuffer array within the
		switch statement above, then move onto the next line ready for the next
		message to arrive on the queue. */
		halLcdPrintLine( cBuffer, ucLine,  OVERWRITE_TEXT );
		ucLine++;
	}
}
Exemple #18
0
/* See the header file for descriptions of public functions. */
xSemaphoreHandle xEMACInit( void )
{
	/* Code supplied by Atmel -------------------------------*/

	/* Disable pull up on RXDV => PHY normal mode (not in test mode),
	PHY has internal pull down. */
	AT91C_BASE_PIOB->PIO_PPUDR = 1 << 15;

	#if USE_RMII_INTERFACE != 1
	  	/* PHY has internal pull down : set MII mode. */
	  	AT91C_BASE_PIOB->PIO_PPUDR = 1 << 16;
	#endif

	/* Clear PB18 <=> PHY powerdown. */
   	AT91C_BASE_PIOB->PIO_PER = 1 << 18;
	AT91C_BASE_PIOB->PIO_OER = 1 << 18;
	AT91C_BASE_PIOB->PIO_CODR = 1 << 18;

	/* After PHY power up, hardware reset. */
	AT91C_BASE_RSTC->RSTC_RMR = emacRESET_KEY | emacRESET_LENGTH;
	AT91C_BASE_RSTC->RSTC_RCR = emacRESET_KEY | AT91C_RSTC_EXTRST;

	/* Wait for hardware reset end. */
	while( !( AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL ) )
	{
		__asm volatile ( "NOP" );
	}
    __asm volatile ( "NOP" );

	/* Setup the pins. */
	AT91C_BASE_PIOB->PIO_ASR = emacPERIPHERAL_A_SETUP;
	AT91C_BASE_PIOB->PIO_PDR = emacPERIPHERAL_A_SETUP;

	/* Enable com between EMAC PHY.

	Enable management port. */
	AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;	

	/* MDC = MCK/32. */
	AT91C_BASE_EMAC->EMAC_NCFGR |= ( 2 ) << 10;	

	/* Wait for PHY auto init end (rather crude delay!). */
	vTaskDelay( emacPHY_INIT_DELAY );

	/* PHY configuration. */
	#if USE_RMII_INTERFACE != 1
	{
		unsigned long ulControl;

		/* PHY has internal pull down : disable MII isolate. */
		vReadPHY( AT91C_PHY_ADDR, MII_BMCR, &ulControl );
		vReadPHY( AT91C_PHY_ADDR, MII_BMCR, &ulControl );
		ulControl &= ~BMCR_ISOLATE;
		vWritePHY( AT91C_PHY_ADDR, MII_BMCR, ulControl );
	}
	#endif

	/* Disable management port again. */
	AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;

	#if USE_RMII_INTERFACE != 1
		/* Enable EMAC in MII mode, enable clock ERXCK and ETXCK. */
		AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN ;
	#else
		/* Enable EMAC in RMII mode, enable RMII clock (50MHz from oscillator
		on ERFCK). */
		AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_RMII | AT91C_EMAC_CLKEN ;
	#endif

	/* End of code supplied by Atmel ------------------------*/

	/* Setup the buffers and descriptors. */
	prvSetupDescriptors();
	
	/* Load our MAC address into the EMAC. */
	prvSetupMACAddress();

	/* Are we connected? */
	if( prvProbePHY() )
	{
		/* Enable the interrupt! */
		portENTER_CRITICAL();
		{
			prvSetupEMACInterrupt();
			vPassEMACSemaphore( xSemaphore );
		}
		portEXIT_CRITICAL();
	}

	return xSemaphore;
}
Exemple #19
0
/**
 * the start thread 
 * 
 * @author rensuiyi (2013/11/23)
 * 
 * @param para 
 */
void start_task(void *para) {
    while (1) {
        vTaskDelay(100);
    }  
}
void broadcast_temperature(void *pvParameters)
{

    uint8_t amount = 0;
    uint8_t sensors = 1;
    ds18b20_addr_t addrs[sensors];
    float results[sensors];
    
    // Use GPIO 13 as one wire pin. 
    uint8_t GPIO_FOR_ONE_WIRE = 13;

    char msg[100];

    // Broadcaster part
    err_t err;

    while(1) {

        // Send out some UDP data
        struct netconn* conn;

        // Create UDP connection
        conn = netconn_new(NETCONN_UDP);

        // Connect to local port
        err = netconn_bind(conn, IP_ADDR_ANY, 8004);

        if (err != ERR_OK) {
            netconn_delete(conn);
            printf("%s : Could not bind! (%s)\n", __FUNCTION__, lwip_strerr(err));
            continue;
        }

        err = netconn_connect(conn, IP_ADDR_BROADCAST, 8005);

        if (err != ERR_OK) {
            netconn_delete(conn);
            printf("%s : Could not connect! (%s)\n", __FUNCTION__, lwip_strerr(err));
            continue;
        }

        for(;;) {
            // Search all DS18B20, return its amount and feed 't' structure with result data.
            amount = ds18b20_scan_devices(GPIO_FOR_ONE_WIRE, addrs, sensors);

            if (amount < sensors){
                printf("Something is wrong, I expect to see %d sensors \nbut just %d was detected!\n", sensors, amount);
            }

            ds18b20_measure_and_read_multi(GPIO_FOR_ONE_WIRE, addrs, sensors, results);
            for (int i = 0; i < sensors; ++i)
            {
                // ("\xC2\xB0" is the degree character (U+00B0) in UTF-8)
                sprintf(msg, "Sensor %08x%08x reports: %f \xC2\xB0""C\n", (uint32_t)(addrs[i] >> 32), (uint32_t)addrs[i], results[i]);
                printf("%s", msg);

                struct netbuf* buf = netbuf_new();
                void* data = netbuf_alloc(buf, strlen(msg));

                memcpy (data, msg, strlen(msg));
                err = netconn_send(conn, buf);

                if (err != ERR_OK) {
                    printf("%s : Could not send data!!! (%s)\n", __FUNCTION__, lwip_strerr(err));
                    continue;
                }
                netbuf_delete(buf); // De-allocate packet buffer
            }
            vTaskDelay(1000/portTICK_RATE_MS);
        }

        err = netconn_disconnect(conn);
        printf("%s : Disconnected from IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err));

        err = netconn_delete(conn);
        printf("%s : Deleted connection (%s)\n", __FUNCTION__, lwip_strerr(err));

        vTaskDelay(1000/portTICK_RATE_MS);
    }
}
Exemple #21
0
static void vPrimaryBlockTimeTestTask( void *pvParameters )
{
BaseType_t xItem, xData;
TickType_t xTimeWhenBlocking;
TickType_t xTimeToBlock, xBlockedTime;

	#ifdef USE_STDIO
	void vPrintDisplayMessage( const char * const * ppcMessageToSend );
	
		const char * const pcTaskStartMsg = "Alt primary block time test started.\r\n";

		/* Queue a message for printing to say the task has started. */
		vPrintDisplayMessage( &pcTaskStartMsg );
	#endif

	( void ) pvParameters;

	for( ;; )
	{
		/*********************************************************************
        Test 1

        Simple block time wakeup test on queue receives. */
		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* The queue is empty. Attempt to read from the queue using a block
			time.  When we wake, ensure the delta in time is as expected. */
			xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;

			/* A critical section is used to minimise the jitter in the time
			measurements. */
			portENTER_CRITICAL();
			{
				xTimeWhenBlocking = xTaskGetTickCount();
				
				/* We should unblock after xTimeToBlock having not received
				anything on the queue. */
				if( xQueueAltReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )
				{
					xErrorOccurred = pdTRUE;
				}

				/* How long were we blocked for? */
				xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
			}
			portEXIT_CRITICAL();

			if( xBlockedTime < xTimeToBlock )
			{
				/* Should not have blocked for less than we requested. */
				xErrorOccurred = pdTRUE;
			}

			if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
			{
				/* Should not have blocked for longer than we requested,
				although we would not necessarily run as soon as we were
				unblocked so a margin is allowed. */
				xErrorOccurred = pdTRUE;
			}
		}


		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif


		/*********************************************************************
        Test 2

        Simple block time wakeup test on queue sends.

		First fill the queue.  It should be empty so all sends should pass. */
		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}
		}

		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* The queue is full. Attempt to write to the queue using a block
			time.  When we wake, ensure the delta in time is as expected. */
			xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;

			portENTER_CRITICAL();
			{
				xTimeWhenBlocking = xTaskGetTickCount();
				
				/* We should unblock after xTimeToBlock having not received
				anything on the queue. */
				if( xQueueAltSendToBack( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )
				{
					xErrorOccurred = pdTRUE;
				}

				/* How long were we blocked for? */
				xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
			}
			portEXIT_CRITICAL();

			if( xBlockedTime < xTimeToBlock )
			{
				/* Should not have blocked for less than we requested. */
				xErrorOccurred = pdTRUE;
			}

			if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
			{
				/* Should not have blocked for longer than we requested,
				although we would not necessarily run as soon as we were
				unblocked so a margin is allowed. */
				xErrorOccurred = pdTRUE;
			}
		}

		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif

		
		/*********************************************************************
        Test 3

		Wake the other task, it will block attempting to post to the queue.
		When we read from the queue the other task will wake, but before it
		can run we will post to the queue again.  When the other task runs it
		will find the queue still full, even though it was woken.  It should
		recognise that its block time has not expired and return to block for
		the remains of its block time.

		Wake the other task so it blocks attempting to post to the already
		full queue. */
		xRunIndicator = 0;
		vTaskResume( xSecondary );

		/* We need to wait a little to ensure the other task executes. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			/* The other task has not yet executed. */
			vTaskDelay( bktSHORT_WAIT );
		}
		/* Make sure the other task is blocked on the queue. */
		vTaskDelay( bktSHORT_WAIT );
		xRunIndicator = 0;

		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* Now when we make space on the queue the other task should wake
			but not execute as this task has higher priority. */				
			if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			/* Now fill the queue again before the other task gets a chance to
			execute.  If the other task had executed we would find the queue
			full ourselves, and the other task have set xRunIndicator. */
			if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed. */
				xErrorOccurred = pdTRUE;
			}

			/* Raise the priority of the other task so it executes and blocks
			on the queue again. */
			vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );

			/* The other task should now have re-blocked without exiting the
			queue function. */
			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed outside of the
				queue function. */
				xErrorOccurred = pdTRUE;
			}

			/* Set the priority back down. */
			vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );			
		}

		/* Let the other task timeout.  When it unblockes it will check that it
		unblocked at the correct time, then suspend itself. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			vTaskDelay( bktSHORT_WAIT );
		}
		vTaskDelay( bktSHORT_WAIT );
		xRunIndicator = 0;

		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif

		/*********************************************************************
        Test 4

		As per test 3 - but with the send and receive the other way around.
		The other task blocks attempting to read from the queue.

		Empty the queue.  We should find that it is full. */
		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}
		}
		
		/* Wake the other task so it blocks attempting to read from  the
		already	empty queue. */
		vTaskResume( xSecondary );

		/* We need to wait a little to ensure the other task executes. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			vTaskDelay( bktSHORT_WAIT );
		}
		vTaskDelay( bktSHORT_WAIT );
		xRunIndicator = 0;

		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* Now when we place an item on the queue the other task should
			wake but not execute as this task has higher priority. */				
			if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			/* Now empty the queue again before the other task gets a chance to
			execute.  If the other task had executed we would find the queue
			empty ourselves, and the other task would be suspended. */
			if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed. */
				xErrorOccurred = pdTRUE;
			}

			/* Raise the priority of the other task so it executes and blocks
			on the queue again. */
			vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );

			/* The other task should now have re-blocked without exiting the
			queue function. */
			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed outside of the
				queue function. */
				xErrorOccurred = pdTRUE;
			}
			vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );			
		}

		/* Let the other task timeout.  When it unblockes it will check that it
		unblocked at the correct time, then suspend itself. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			vTaskDelay( bktSHORT_WAIT );
		}
		vTaskDelay( bktSHORT_WAIT );

		xPrimaryCycles++;
	}
}
Exemple #22
0
void sys_arch_msleep(u32_t delay_ms)
{
    TickType_t delay_ticks = delay_ms / portTICK_PERIOD_MS;
    vTaskDelay(delay_ticks);
}
Exemple #23
0
void CPLR_Task( void* pvParameters )
{
   (void) pvParameters;
   QEvt const *evt; /* This pointer to an event always lives but should be
                       garbage collected after finishing to process it so the
                       memory in the pool to which it points can be reused. If
                       this thread needs to wait on another event while still
                       processing this (main) one, a different local pointer
                       should be used and garbage collected after. */

   DC3Error_t status = ERR_NONE; /* Keep track of failures of various func
                                     calls and commands.  If this is ever set
                                     to something other than ERR_NONE, it will
                                     be printed out at the end of the for loop*/

   for (;;) {                         /* Beginning of the thread forever loop */
      /* Check if there's data in the queue and process it if there. */

      evt = QEQueue_get(&CPLR_evtQueue);
      if ( evt != (QEvt *)0 ) { /* Check whether an event is present in queue */

         switch( evt->sig ) {        /* Identify the event by its signal enum */
            case CPLR_ETH_SYS_TEST_SIG:
               DBG_printf(
                     "Received CPLR_ETH_SYS_TEST_SIG (%d) signal with event EthEvt of len: %d\n",
                     evt->sig,
                     ((EthEvt const *)evt)->msg_len
               );
#if 0
               /* Going to use this signal to test some stuff in this thread */
               /* Do a read from the EEPROM on the I2C Bus */
               status = I2C_readDevMemEVT(
                     _DC3_EEPROM,                                    // DC3I2CDevice_t iDev,
                     0x00,                                           // uint16_t offset,
                     17,                                             // uint16_t bytesToRead,
                     _DC3_ACCESS_FRT,                                // AccessType_t accType,
                     NULL                                            // QActive* callingAO
               );
               if ( ERR_NONE != status ) {
                  ERR_printf("Error calling I2C_readDevMemEVT()\n");
                  goto CPLR_Task_ERR_HANDLE; /* Stop and jump to error handling */
               }

               /* If we got here, there were no errors during the call to
                * I2C_readDevMemEVT() so we can expect an event from that driver
                */
               uint32_t timeout = 1000;
               QEvt const *evtI2CDone = 0;

               /* We only expect an I2C read done signal and no others */
               do {
                  evtI2CDone = QEQueue_get(&CPLR_evtQueue);
                  if (evtI2CDone != (QEvt *)0 ) {
                     break;
                  } else {
                     vTaskDelay(1);
                  }
               } while ( --timeout != 0 );

               if ( 0 == timeout ) {
                  ERR_printf("Timed out waiting for an event\n");
               } else {
                  switch( evtI2CDone->sig ) {
                     case I2C1_DEV_READ_DONE_SIG:
                        DBG_printf("Got I2C1_DEV_READ_DONE_SIG\n");
                        break;
                     default:
                        WRN_printf("Unknown signal %d\n", evtI2CDone->sig);
                        break;
                  }
                  QF_gc(evt);
               }

#endif
               uint8_t buffer[20];
               uint16_t bytesRead = 0;

               DBG_printf("Issuing I2C_readDevMemFRT()\n");
               status = I2C_readDevMemFRT(
                     _DC3_EEPROM,                     // const DC3I2CDevice_t iDev,
                     0x00,                            // const uint16_t offset,
                     17,                              // const uint16_t nBytesToRead
                     sizeof(buffer),                  // const uint16_t nBufferSize,
                     buffer,                          // uint8_t const *pBuffer,
                     &bytesRead                       // uint16_t *pBytesRead,
               );

               char tmp[120];
               uint16_t tmpLen = 0;
               status = CON_hexToStr(
                     (const uint8_t *)buffer,             // data to convert
                     bytesRead,                           // length of data to convert
                     tmp,                                 // where to write output
                     sizeof(tmp),                         // max size of output buffer
                     &tmpLen,                             // size of the resulting output
                     0,                                   // no columns
                     ' ',                                 // separator
                     true                                 // bPrintX
               );
               DBG_printf("I2C_readDevMemFRT() returned having read %d bytes: %s\n", bytesRead, tmp);
               break;

            default:
               WRN_printf("Received an unknown signal: %d. Ignoring...\n", evt->sig);
               break;

         }
         /* If any data from the event needs to be used after garbage
          * collection, it should be locally stored if. */


CPLR_Task_ERR_HANDLE:             /* Handle any error that may have occurred. */
         /* Print error if exists */
         ERR_COND_OUTPUT(
               status,
               _DC3_ACCESS_FRT,
               "Error 0x%08x occurred in FreeRTOS thread!!!\n",
               status
         );

         QF_gc(evt); /* !!! Don't forget to garbage collect the event after
                        processing the event.  After this, any data to which
                        this pointer points to may not be valid and should not
                        be referenced. */
      }

//      vTaskSuspend(NULL);
      vTaskDelay(1); /* Always task-delay so this thread can go to sleep while
                        other threads/AOs can process their data */
   }                                        /* End of the thread forever loop */
}
Exemple #24
0
/*
 * Controller task as described above.
 */
static void vCounterControlTask( void * pvParameters )
{
    unsigned long ulLastCounter;
    short sLoops;
    short sError = pdFALSE;
    const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n";
    const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n";

    /* Just to stop warning messages. */
    ( void ) pvParameters;

    /* Queue a message for printing to say the task has started. */
    vPrintDisplayMessage( &pcTaskStartMsg );

    for( ;; )
    {
        /* Start with the counter at zero. */
        ulCounter = ( unsigned long ) 0;

        /* First section : */

        /* Check the continuous count task is running. */
        for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
        {
            /* Suspend the continuous count task so we can take a mirror of the
            shared variable without risk of corruption. */
            vTaskSuspend( xContinuousIncrementHandle );
            ulLastCounter = ulCounter;
            vTaskResume( xContinuousIncrementHandle );

            /* Now delay to ensure the other task has processor time. */
            vTaskDelay( priSLEEP_TIME );

            /* Check the shared variable again.  This time to ensure mutual
            exclusion the whole scheduler will be locked.  This is just for
            demo purposes! */
            vTaskSuspendAll();
            {
                if( ulLastCounter == ulCounter )
                {
                    /* The shared variable has not changed.  There is a problem
                    with the continuous count task so flag an error. */
                    sError = pdTRUE;
                    xTaskResumeAll();
                    vPrintDisplayMessage( &pcTaskFailMsg );
                    vTaskSuspendAll();
                }
            }
            xTaskResumeAll();
        }


        /* Second section: */

        /* Suspend the continuous counter task so it stops accessing the shared variable. */
        vTaskSuspend( xContinuousIncrementHandle );

        /* Reset the variable. */
        ulCounter = ( unsigned long ) 0;

        /* Resume the limited count task which has a higher priority than us.
        We should therefore not return from this call until the limited count
        task has suspended itself with a known value in the counter variable.
        The scheduler suspension is not necessary but is included for test
        purposes. */
        vTaskSuspendAll();
        vTaskResume( xLimitedIncrementHandle );
        xTaskResumeAll();

        /* Does the counter variable have the expected value? */
        if( ulCounter != priMAX_COUNT )
        {
            sError = pdTRUE;
            vPrintDisplayMessage( &pcTaskFailMsg );
        }

        if( sError == pdFALSE )
        {
            /* If no errors have occurred then increment the check variable. */
            portENTER_CRITICAL();
            usCheckVariable++;
            portEXIT_CRITICAL();
        }

#if configUSE_PREEMPTION == 0
        taskYIELD();
#endif

        /* Resume the continuous count task and do it all again. */
        vTaskResume( xContinuousIncrementHandle );
    }
}
Exemple #25
0
void camera_task(void *pv) {
  
  vTaskDelay(100);
  /*
  Camera_Cmd(ENABLE);
  Camera_Record_Snippet(4000);
  vTaskDelay(1000);
  Camera_Cmd(DISABLE);
  */
  vTaskDelay(100);
  
  vTaskDelay(100);
  
  {
    FATFS fs;
    FIL file;
    
    if(f_mount(0, &fs) != FR_OK)
      while(1) ;
    
    if(f_open(&file, "temp1.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK)
      while(1) ;
    
    uint32_t bytes_written = 0;
    f_write(&file, "test\r\n", 6, &bytes_written);
    
    f_sync(&file);
    f_close(&file);
    
    f_mount(0, NULL);
    
    uint8_t cmd = 0;
    disk_ioctl(0, CTRL_POWER, &cmd);
    
    if(f_mount(0, &fs) != FR_OK)
      while(1) ;
    
    if(f_open(&file, "temp2.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK)
      while(1) ;
    
    bytes_written = 0;
    f_write(&file, "test\r\n", 6, &bytes_written);
    
    f_sync(&file);
    f_close(&file);
    
    f_mount(0, NULL);
        
    
  }
  
  
  vTaskDelay(100);
  
  
  vTaskDelay(100);
  /*
  Camera_Cmd(ENABLE);
  Camera_Record_Snippet(4000);
  vTaskDelay(1000);
  Camera_Cmd(DISABLE);
  
  vTaskDelay(100);
  */
  vTaskSuspend(NULL);
}
Exemple #26
0
static void prvChangePriorityWhenSuspendedTask( void *pvParameters )
{
    const char * const pcTaskStartMsg = "Priority change when suspended task started.\r\n";
    const char * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n";

    /* Just to stop warning messages. */
    ( void ) pvParameters;

    /* Queue a message for printing to say the task has started. */
    vPrintDisplayMessage( &pcTaskStartMsg );

    for( ;; )
    {
        /* Start with the counter at 0 so we know what the counter should be
        when we check it next. */
        ulPrioritySetCounter = ( unsigned long ) 0;

        /* Resume the helper task.  At this time it has a priority lower than
        ours so no context switch should occur. */
        vTaskResume( xChangePriorityWhenSuspendedHandle );

        /* Check to ensure the task just resumed has not executed. */
        portENTER_CRITICAL();
        {
            if( ulPrioritySetCounter != ( unsigned long ) 0 )
            {
                xPriorityRaiseWhenSuspendedError = pdTRUE;
                vPrintDisplayMessage( &pcTaskFailMsg );
            }
        }
        portEXIT_CRITICAL();

        /* Now try raising the priority while the scheduler is suspended. */
        vTaskSuspendAll();
        {
            vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) );

            /* Again, even though the helper task has a priority greater than
            ours, it should not have executed yet because the scheduler is
            suspended. */
            portENTER_CRITICAL();
            {
                if( ulPrioritySetCounter != ( unsigned long ) 0 )
                {
                    xPriorityRaiseWhenSuspendedError = pdTRUE;
                    vPrintDisplayMessage( &pcTaskFailMsg );
                }
            }
            portEXIT_CRITICAL();
        }
        xTaskResumeAll();

        /* Now the scheduler has been resumed the helper task should
        immediately preempt us and execute.  When it executes it will increment
        the ulPrioritySetCounter exactly once before suspending itself.

        We should now always find the counter set to 1. */
        portENTER_CRITICAL();
        {
            if( ulPrioritySetCounter != ( unsigned long ) 1 )
            {
                xPriorityRaiseWhenSuspendedError = pdTRUE;
                vPrintDisplayMessage( &pcTaskFailMsg );
            }
        }
        portEXIT_CRITICAL();

        /* Delay until we try this again. */
        vTaskDelay( priSLEEP_TIME * 2 );

        /* Set the priority of the helper task back ready for the next
        execution of this task. */
        vTaskSuspendAll();
        vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY );
        xTaskResumeAll();
    }
}
/**
 * \brief UART task
 *
 * This task runs in the background to handle the queued, incoming terminal
 * characters and write them to the terminal text buffer. It does not print
 * anything to the display -- that is done by \ref terminal_task().
 *
 * \param params Parameters for the task. (Not used.)
 */
static void uart_task(void *params)
{
	uint8_t *current_line_ptr;
	uint8_t *current_char_ptr;
	uint8_t current_column = 0;

	for (;;) {
		// Show that task is executing
		oled1_set_led_state(&oled1, OLED1_LED1_ID, true);

		// Grab terminal mutex
		xSemaphoreTake(terminal_mutex, portMAX_DELAY);

		current_line_ptr = terminal_buffer[terminal_line_offset];
		current_char_ptr = current_line_ptr + current_column;

		// Any characters queued? Handle them!
		while (xQueueReceive(terminal_in_queue, current_char_ptr, 0)) {
			/* Newline-handling is difficult because all terminal emulators
			 * seem to do it their own way. The method below seems to work
			 * with Putty and Realterm out of the box.
			 */
			switch (*current_char_ptr) {
			case '\r':
				// Replace \r with \0 and move head to next line
				*current_char_ptr = '\0';

				current_column = 0;
				terminal_line_offset = (terminal_line_offset + 1)
						% TERMINAL_BUFFER_LINES;
				current_line_ptr = terminal_buffer[terminal_line_offset];
				current_char_ptr = current_line_ptr + current_column;
				break;

			case '\n':
				// For \n, do nothing -- it is replaced with \0 later
				break;

			default:
				// For all other characters, just move head to next char
				current_column++;
				if (current_column >= TERMINAL_COLUMNS) {
					current_column = 0;
					terminal_line_offset = (terminal_line_offset + 1)
							% TERMINAL_BUFFER_LINES;
					current_line_ptr = terminal_buffer[terminal_line_offset];
				}
				current_char_ptr = current_line_ptr + current_column;
			}

			// Set zero-terminator at head
			*current_char_ptr = '\0';
		}

		xSemaphoreGive(terminal_mutex);

		oled1_set_led_state(&oled1, OLED1_LED1_ID, false);

		vTaskDelay(UART_TASK_DELAY);
	}
}
Exemple #28
0
// For BCT hut-plugging test
void cmd_interface(int argc, char **argv)
{
	if(argc == 1) goto error;

	if(strcmp(argv[1], "set") == 0) {
		if((argc == 4) || (argc == 5)) {
			struct ip_addr ip_addr;
			struct ip_addr netmask_addr;
			struct ip_addr gw_addr;
			uint32_t ip[4], netmask[4], gw[4];
			char *ptr, *head, *tail;
			int i;

			ptr = argv[2];
			for(i = 0; i < 4; i ++) {
				head = ptr;
				while(*ptr && *ptr != '.') ptr ++;
				tail = ptr ++;
				*tail = 0;
				ip[i] = atoi(head);
			}

			ptr = argv[3];
			for(i = 0; i < 4; i ++) {
				head = ptr;
				while(*ptr && *ptr != '.') ptr ++;
				tail = ptr ++;
				*tail = 0;
				netmask[i] = atoi(head);
			}

			if(argc == 5) {
				ptr = argv[4];
				for(i = 0; i < 4; i ++) {
					head = ptr;
					while(*ptr && *ptr != '.') ptr ++;
					tail = ptr ++;
					*tail = 0;
					gw[i] = atoi(head);
				}
			}
			else {
				memset(gw, 0, sizeof(gw));
			}

			IP4_ADDR(&ip_addr, ip[0], ip[1], ip[2], ip[3]);
			IP4_ADDR(&netmask_addr, netmask[0], netmask[1], netmask[2], netmask[3]);
			IP4_ADDR(&gw_addr, gw[0], gw[1], gw[2], gw[3]);
			netif_set_addr(&xnetif[0], &ip_addr , &netmask_addr, &gw_addr);

			printf("\nSet IP  : %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
			printf(  "    MASK: %d.%d.%d.%d\n", netmask[0], netmask[1], netmask[2], netmask[3]);
			printf(  "    GW  : %d.%d.%d.%d\n", gw[0], gw[1], gw[2], gw[3]);
		}
		else {
			printf("Usage: interface set IP NETMASK [GATEWAY]\n");
		}
	}
	else if(strcmp(argv[1], "info") == 0) {
		u8 *mac = LwIP_GetMAC(&xnetif[0]);
		u8 *ip = LwIP_GetIP(&xnetif[0]);
		u8 *netmask = LwIP_GetMASK(&xnetif[0]);
		u8 *gw = LwIP_GetGW(&xnetif[0]);
		printf("\n MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
		printf("\nIPv4 Address : %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
		printf(  "     Netmask : %d.%d.%d.%d\n", netmask[0], netmask[1], netmask[2], netmask[3]);
		printf(  "     Gateway : %d.%d.%d.%d\n", gw[0], gw[1], gw[2], gw[3]);
#if LWIP_IPV6
		uint8_t *ipv6 = (uint8_t *) &(xnetif[0].ip6_addr[0].addr[0]);
		printf("\nIPv6 Address : %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
		       ipv6[0], ipv6[1],  ipv6[2],  ipv6[3],  ipv6[4],  ipv6[5],  ipv6[6], ipv6[7],
		       ipv6[8], ipv6[9], ipv6[10], ipv6[11], ipv6[12], ipv6[13], ipv6[14], ipv6[15]);
#endif
	}
	else if(strcmp(argv[1], "disconnect") == 0) {
		int timeout = 20;
		char essid[33];

		if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) {
			printf("\nWIFI disconnected\n");
			return;
		}

		wifi_disconnect();

		while(1) {
			if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) {
				printf("\nWIFI disconnected\n");
				break;
			}
			if(timeout == 0) {
				printf("\nERROR: Operation failed!\n");
				break;
			}
			vTaskDelay(1000);
			timeout --;
		}
	}
	else if(strcmp(argv[1], "reconnect") == 0) {
		HomeKitNetworkConnection();
	}
	else {
error:
		printf("Usage: interface set|info|disconnect|reconnect\n");
	}
}
/*!
 * \brief The task function for the "Check" task.
 */
static void vErrorChecks( void *pvParameters )
{
static volatile unsigned long ulDummyVariable = 3UL;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0;

	/* The parameters are not used.  Prevent compiler warnings. */
	( void ) pvParameters;

	/* Cycle for ever, delaying then checking all the other tasks are still
	operating without error.

	In addition to the standard tests the memory allocator is tested through
	the dynamic creation and deletion of a task each cycle.  Each time the
	task is created memory must be allocated for its stack.  When the task is
	deleted this memory is returned to the heap.  If the task cannot be created
	then it is likely that the memory allocation failed. */

	for( ;; )
	{
		/* Do this only once. */
		if( bSuicidalTask == 0 )
		{
			bSuicidalTask++;

			/* This task has to be created last as it keeps account of the number of
			tasks it expects to see running. However its implementation expects
			to be called before vTaskStartScheduler(). We're in the case here where
			vTaskStartScheduler() has already been called (thus the hidden IDLE task
			has already been spawned). Since vCreateSuicidalTask() supposes that the
			IDLE task isn't included in the response from uxTaskGetNumberOfTasks(),
			let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks()
			is not called as the last task. */
			vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
		}

		/* Reset xCreatedTask.  This is modified by the task about to be
		created so we can tell if it is executing correctly or not. */
		xCreatedTask = mainNO_TASK;

		/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
		parameter. */
		ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;

		if( xTaskCreate( vMemCheckTask,
			"MEM_CHECK",
			configMINIMAL_STACK_SIZE,
			( void * ) &ulMemCheckTaskRunningCount,
			tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
		{
			/* Could not create the task - we have probably run out of heap.
			Don't go any further and flash the LED faster to provide visual
			feedback of the error. */
			prvIndicateError();
		}

		/* Delay until it is time to execute again. */
		vTaskDelay( mainCHECK_PERIOD );

		/* Delete the dynamically created task. */
		if( xCreatedTask != mainNO_TASK )
		{
			vTaskDelete( xCreatedTask );
		}

		/* Perform a bit of 32bit maths to ensure the registers used by the
		integer tasks get some exercise. The result here is not important -
		see the demo application documentation for more info. */
		ulDummyVariable *= 3;

		/* Check all other tasks are still operating without error.
		Check that vMemCheckTask did increment the counter. */
		if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE )
		 || ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
		{
			/* An error has occurred in one of the tasks.
			Don't go any further and flash the LED faster to give visual
			feedback of the error. */
			prvIndicateError();
		}
		else
		{
			/* Toggle the LED if everything is okay. */
			vParTestToggleLED( mainCHECK_TASK_LED );
		}
	}
}
static void vComRxTask( void *pvParameters )
{
BaseType_t xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE;
char *pcExpectedByte, cRxedChar;
const xComPortHandle xPort = NULL;

	/* The parameter is not used in this example. */
	( void ) pvParameters;

	/* Start the Tx timer.  This only needs to be started once, as it will
	reset itself thereafter. */
	xTimerStart( xTxTimer, portMAX_DELAY );

	/* The first expected Rx character is the first in the string that is
	transmitted. */
	pcExpectedByte = comTRANSACTED_STRING;

	for( ;; )
	{
		/* Wait for the next character. */
		if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE )
		{
			/* A character definitely should have been received by now.  As a
			character was not received an error must have occurred (which might
			just be that the loopback connector is not fitted). */
			xErrorOccurred = pdTRUE;
		}

		switch( xState )
		{
			case comtstWAITING_START_OF_STRING:
				if( cRxedChar == *pcExpectedByte )
				{
					/* The received character was the first character of the
					string.  Move to the next state to check each character
					as it comes in until the entire string has been received. */
					xState = comtstWAITING_END_OF_STRING;
					pcExpectedByte++;

					/* Block for a short period.  This just allows the Rx queue
					to contain more than one character, and therefore prevent
					thrashing reads to the queue, and repetitive context
					switches as	each character is received. */
					vTaskDelay( comSHORT_DELAY );
				}
				break;

			case comtstWAITING_END_OF_STRING:
				if( cRxedChar == *pcExpectedByte )
				{
					/* The received character was the expected character.  Was
					it the last character in the string - i.e. the null
					terminator? */
					if( cRxedChar == 0x00 )
					{
						/* The entire string has been received.  If no errors
						have been latched, then increment the loop counter to
						show this task is still healthy. */
						if( xErrorOccurred == pdFALSE )
						{
							uxRxLoops++;

							/* Toggle an LED to give a visible sign that a
							complete string has been received. */
							vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET );
						}

						/* Go back to wait for the start of the next string. */
						pcExpectedByte = comTRANSACTED_STRING;
						xState = comtstWAITING_START_OF_STRING;
					}
					else
					{
						/* Wait for the next character in the string. */
						pcExpectedByte++;
					}
				}
				else
				{
					/* The character received was not that expected. */
					xErrorOccurred = pdTRUE;
				}
				break;

			default:
				/* Should not get here.  Stop the Rx loop counter from
				incrementing to latch the error. */
				xErrorOccurred = pdTRUE;
				break;
		}
	}
}