/**
  * An internal method that either spin waits if mode is set to SYNC_SPINWAIT
  * or puts the fiber to sleep if the mode is set to SYNC_SLEEP
  *
  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP
  */
void MicroBitSerial::send(MicroBitSerialMode mode)
{
    if(mode == SYNC_SPINWAIT)
        while(txBufferedSize() > 0);

    if(mode == SYNC_SLEEP)
        fiber_sleep(0);
}
Example #2
0
static void tx_fiber(void)
{
	BT_DBG("");

	/* FIXME: make periodic sending */
	h5_send(sync_req, HCI_3WIRE_LINK_PKT, sizeof(sync_req));

	while (true) {
		struct net_buf *buf;
		uint8_t type;

		BT_DBG("link_state %u", h5.link_state);

		switch (h5.link_state) {
		case UNINIT:
			/* FIXME: send sync */
			fiber_sleep(10);
			break;
		case INIT:
			/* FIXME: send conf */
			fiber_sleep(10);
			break;
		case ACTIVE:
			buf = nano_fifo_get(&h5.tx_queue, TICKS_UNLIMITED);
			type = h5_get_type(buf);

			h5_send(buf->data, type, buf->len);

			/* buf is dequeued from tx_queue and queued to unack
			 * queue.
			 */
			nano_fifo_put(&h5.unack_queue, buf);
			unack_queue_len++;

			if (h5.retx_to) {
				fiber_delayed_start_cancel(h5.retx_to);
			}

			h5.retx_to = fiber_delayed_start(retx_stack,
							 sizeof(retx_stack),
							 retx_fiber, 0, 0, 7, 0,
							 H5_TX_ACK_TIMEOUT);
			break;
		}
	}
}
Example #3
0
File: tcp.c Project: hudkmr/zephyr
int tcp_tx(struct net_context *ctx, uint8_t *buf,  size_t size)
{
	struct net_buf *nbuf = NULL;
	uint8_t *ptr;
	int rc = 0;

	nbuf = ip_buf_get_tx(ctx);
	if (nbuf == NULL) {
		printk("[%s:%d] Unable to get buffer\n", __func__, __LINE__);
		return -EINVAL;
	}

	ptr = net_buf_add(nbuf, size);
	memcpy(ptr, buf, size);
	ip_buf_appdatalen(nbuf) = size;

	do {
		rc = net_send(nbuf);
		if (rc >= 0) {
			ip_buf_unref(nbuf);
			return 0;
		}
		switch (rc) {
		case -EINPROGRESS:
			printk("%s: no connection yet, try again\n", __func__);
			fiber_sleep(TCP_RETRY_TIMEOUT);
			break;
		case -EAGAIN:
		case -ECONNRESET:
			printk("%s: no connection, try again later\n", __func__);
			fiber_sleep(TCP_RETRY_TIMEOUT);
			break;
		default:
			printk("%s: sending %d bytes failed\n",
			      __func__, size);
			ip_buf_unref(nbuf);
			return -EIO;
		}
	} while (1);

	return 0;
}
Example #4
0
int
test_reload(box_function_ctx_t *ctx, const char *args, const char *args_end)
{
	fiber_sleep(0.001);
	char tuple_buf[64];
	char *tuple_end = tuple_buf;
	tuple_end = mp_encode_array(tuple_end, 1);
	tuple_end = mp_encode_uint(tuple_end, 2);
	struct tuple *tuple = box_tuple_new(box_tuple_format_default(), tuple_buf, tuple_end);
	return box_return_tuple(ctx, tuple);
}
Example #5
0
/* a fiber sleeps and times out, then reports through a fifo */
static void test_fiber_sleep(int timeout, int arg2)
{
	int64_t orig_ticks = sys_tick_get();

	TC_PRINT(" fiber sleeping for %d ticks\n", timeout);
	fiber_sleep(timeout);
	TC_PRINT(" fiber back from sleep\n");
	if (!is_timeout_in_range(orig_ticks, timeout)) {
		return;
	}

	nano_fiber_sem_give(&reply_timeout);
}
Example #6
0
static void
fiber_cond_basic()
{
	struct fiber_cond *cond = fiber_cond_new();
	int check = 0;

	struct fiber *f1 = fiber_new("f1", fiber_cond_basic_f);
	assert(f1 != NULL);
	fiber_start(f1, cond, &check);
	fiber_set_joinable(f1, true);

	struct fiber *f2 = fiber_new("f2", fiber_cond_basic_f);
	assert(f2 != NULL);
	fiber_start(f2, cond, &check);
	fiber_set_joinable(f2, true);

	/* check timeout */
	fiber_sleep(0.0);
	fiber_sleep(0.0);

	/* Wake up the first fiber */
	fiber_cond_signal(cond);
	fiber_sleep(0.0);

	/* Wake ip the second fiber */
	fiber_cond_signal(cond);
	fiber_sleep(0.0);

	/* Check that fiber scheduling is fair */
	is(check, 2, "order");

	fiber_cond_broadcast(cond);
	fiber_sleep(0.0);

	fiber_join(f1);
	fiber_join(f2);

	fiber_cond_delete(cond);
}
Example #7
0
 //% help=basic/show-string 
 //% weight=87 blockGap=8
 //% block="show|string %text" icon="\uf031" 
 //% async
 //% blockId=device_print_message
 void showString(StringData *text, int interval = 150) {
   if (interval < 0)
     return;
   ManagedString s(text);
   int l = s.length();
   if (l == 0) {
     uBit.display.clear();
     fiber_sleep(interval * 5);
   } else if (l > 1) {
     uBit.display.scroll(s, interval);
   } else {
     uBit.display.print(s.charAt(0), interval * 5);
   }
 }
Example #8
0
static void errno_fiber(int n, int my_errno)
{
	errno = my_errno;

	printk("fiber %d, errno before sleep: %x\n", n, errno);

	fiber_sleep(3 - n);
	if (errno == my_errno) {
		result[n].pass = 1;
	}

	printk("fiber %d, errno after sleep:  %x\n", n, errno);

	nano_fiber_fifo_put(&fifo, &result[n]);
}
Example #9
0
 //% help=pins/analog-pitch weight=14 async
 void analogPitch(int frequency, int ms) { 
   if (pitchPin == NULL) return;
   if (frequency <= 0) {
     pitchPin->setAnalogValue(0);
   } else {
     pitchPin->setAnalogValue(512);
     pitchPin->setAnalogPeriodUs(1000000/frequency);
   }
   
   if (ms > 0) {
       fiber_sleep(ms);
       pitchPin->setAnalogValue(0);
       // TODO why do we use wait_ms() here? it's a busy wait I think
       wait_ms(5);
   }
 }
    inline bool wait_for_data() {
      m_mutex.lock();
      bool success = false;
      // Wait while the queue is empty and this queue is alive
      while(m_queue.empty() && m_alive) {
        sleeping++;
        fiber_sleep();
        sleeping--;
      }
      // An element has been added or a signal was raised
      if(!m_queue.empty()) {
        success = true;
      } 
      m_mutex.unlock();

      return success; 
    }
    /**
     * Blocks until an element is available in the queue 
     * or until stop_blocking() is called.
     * The return value is a pair of <T value, bool success>
     * If "success" if set, then "value" is valid and 
     * is an element popped from the queue.
     * If "success" is false, stop_blocking() was called 
     * and the queue has been destroyed.
     */
    inline std::pair<T, bool> dequeue() {

      m_mutex.lock();
      T elem = T();
      bool success = false;
      // Wait while the queue is empty and this queue is alive
      while(m_queue.empty() && m_alive) {
        sleeping++;
        fiber_sleep();
        sleeping--;
      }
      // An element has been added or a signal was raised
      if(!m_queue.empty()) {
        success = true;
        elem = m_queue.front();
        m_queue.pop_front();
      } 
      m_mutex.unlock();

      return std::make_pair(elem, success);
    }
Example #12
0
static void test_fiber(int arg1, int arg2)
{
	uint32_t start_tick;
	uint32_t end_tick;

	nano_fiber_sem_take(&test_fiber_sem, TICKS_UNLIMITED);

	TC_PRINT("Testing normal expiration of fiber_sleep()\n");
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick != start_tick + ONE_SECOND) {
		TC_ERROR(" *** fiber_sleep() slept for %d ticks not %d.",
				 end_tick - start_tick, ONE_SECOND);

		return;
	}

	TC_PRINT("Testing fiber_sleep() + fiber_fiber_wakeup()\n");
	nano_fiber_sem_give(&helper_fiber_sem);   /* Activate helper fiber */
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick > start_tick) {
		TC_ERROR(" *** fiber_fiber_wakeup() took too long (%d ticks)\n",
				 end_tick - start_tick);
		return;
	}

	TC_PRINT("Testing fiber_sleep() + isr_fiber_wakeup()\n");
	nano_fiber_sem_give(&helper_fiber_sem);   /* Activate helper fiber */
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick > start_tick) {
		TC_ERROR(" *** isr_fiber_wakeup() took too long (%d ticks)\n",
				 end_tick - start_tick);
		return;
	}

	TC_PRINT("Testing fiber_sleep() + task_fiber_wakeup()\n");
	nano_task_sem_give(&task_sem);    /* Activate task */
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);           /* Task will execute */
	end_tick = sys_tick_get_32();

	if (end_tick > start_tick) {
		TC_ERROR(" *** task_fiber_wakeup() took too long (%d ticks)\n",
				 end_tick - start_tick);
		return;
	}

	test_failure = false;
}
Example #13
0
/* a fiber sleeps then puts data on the lifo */
static void test_fiber_put_timeout(int lifo, int timeout)
{
	fiber_sleep((int32_t)timeout);
	nano_fiber_lifo_put((struct nano_lifo *)lifo, get_scratch_packet());
}
Example #14
0
 void forever_stub(void *a) {
   while (true) {
     runAction0((Action)a);
     fiber_sleep(20);
   }
 }
Example #15
0
 //% help=basic/pause weight=54
 //% async block="pause (ms) %pause"
 //% blockId=device_pause icon="\uf110"
 void pause(int ms) {
   fiber_sleep(ms);
 }
Example #16
0
int bt_enable(bt_ready_cb_t cb)
{
	struct device *gpio;
	int ret;

	BT_DBG("");

	gpio = device_get_binding(CONFIG_GPIO_DW_0_NAME);
	if (!gpio) {
		BT_ERR("Cannot find %s", CONFIG_GPIO_DW_0_NAME);
		return -ENODEV;
	}

	ret = gpio_pin_configure(gpio, NBLE_RESET_PIN, GPIO_DIR_OUT);
	if (ret) {
		BT_ERR("Error configuring pin %d", NBLE_RESET_PIN);
		return -ENODEV;
	}

	/* Reset hold time is 0.2us (normal) or 100us (SWD debug) */
	ret = gpio_pin_write(gpio, NBLE_RESET_PIN, 0);
	if (ret) {
		BT_ERR("Error pin write %d", NBLE_RESET_PIN);
		return -EINVAL;
	}

	ret = gpio_pin_configure(gpio, NBLE_BTWAKE_PIN, GPIO_DIR_OUT);
	if (ret) {
		BT_ERR("Error configuring pin %d", NBLE_BTWAKE_PIN);
		return -ENODEV;
	}

	ret = gpio_pin_write(gpio, NBLE_BTWAKE_PIN, 1);
	if (ret) {
		BT_ERR("Error pin write %d", NBLE_BTWAKE_PIN);
		return -EINVAL;
	}

	/**
	 * NBLE reset is achieved by asserting low the SWDIO pin.
	 * However, the BLE Core chip can be in SWD debug mode,
	 * and NRF_POWER->RESET = 0 due to, other constraints: therefore,
	 * this reset might not work everytime, especially after
	 * flashing or debugging.
	 */

	/* sleep 1ms depending on context */
	switch (sys_execution_context_type_get()) {
	case NANO_CTX_FIBER:
		fiber_sleep(MSEC(1));
		break;
	case NANO_CTX_TASK:
		task_sleep(MSEC(1));
		break;
	default:
		BT_ERR("ISR context is not supported");
		return -EINVAL;
	}

	ret = nble_open();
	if (ret) {
		return ret;
	}

	ret = gpio_pin_write(gpio, NBLE_RESET_PIN, 1);
	if (ret) {
		BT_ERR("Error pin write %d", NBLE_RESET_PIN);
		return -EINVAL;
	}

	/* Set back GPIO to input to avoid interfering with external debugger */
	ret = gpio_pin_configure(gpio, NBLE_RESET_PIN, GPIO_DIR_IN);
	if (ret) {
		BT_ERR("Error configuring pin %d", NBLE_RESET_PIN);
		return -ENODEV;
	}

	bt_ready_cb = cb;

	return 0;
}
/**
 * Enter pairing mode. This is mode is called to initiate pairing, and to enable FOTA programming
 * of the micro:bit in cases where BLE is disabled during normal operation.
 *
 * @param display An instance of MicroBitDisplay used when displaying pairing information.
 * @param authorizationButton The button to use to authorise a pairing request.
 *
 * @code
 * // initiate pairing mode
 * bleManager.pairingMode(uBit.display, uBit.buttonA);
 * @endcode
 */
void MicroBitBLEManager::pairingMode(MicroBitDisplay& display, MicroBitButton& authorisationButton)
{
	ManagedString namePrefix("BBC micro:bit [");
	ManagedString namePostfix("]");
	ManagedString BLEName = namePrefix + deviceName + namePostfix;

	ManagedString msg("PAIRING MODE!");

	int timeInPairingMode = 0;
	int brightness = 255;
	int fadeDirection = 0;

    ble->gap().stopAdvertising();

    // Clear the whitelist (if we have one), so that we're discoverable by all BLE devices.
#if CONFIG_ENABLED(MICROBIT_BLE_WHITELIST)
    BLEProtocol::Address_t addresses[MICROBIT_BLE_MAXIMUM_BONDS];
    Gap::Whitelist_t whitelist;
    whitelist.addresses = addresses;
    whitelist.capacity = MICROBIT_BLE_MAXIMUM_BONDS;
    whitelist.size = 0;
    ble->gap().setWhitelist(whitelist);
    ble->gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST);
#endif

	// Update the advertised name of this micro:bit to include the device name
    ble->clearAdvertisingPayload();

    ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)BLEName.toCharArray(), BLEName.length());
    ble->setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble->setAdvertisingInterval(200);

    ble->gap().setAdvertisingTimeout(0);
    ble->gap().startAdvertising();

	// Stop any running animations on the display
	display.stopAnimation();
	display.scroll(msg);

	// Display our name, visualised as a histogram in the display to aid identification.
	showNameHistogram(display);

	while(1)
	{
		if (pairingStatus & MICROBIT_BLE_PAIR_REQUEST)
		{
			timeInPairingMode = 0;
			MicroBitImage arrow("0,0,255,0,0\n0,255,0,0,0\n255,255,255,255,255\n0,255,0,0,0\n0,0,255,0,0\n");
			display.print(arrow,0,0,0);

			if (fadeDirection == 0)
				brightness -= MICROBIT_PAIRING_FADE_SPEED;
			else
				brightness += MICROBIT_PAIRING_FADE_SPEED;

			if (brightness <= 40)
				display.clear();

			if (brightness <= 0)
				fadeDirection = 1;

			if (brightness >= 255)
				fadeDirection = 0;

			if (authorisationButton.isPressed())
			{
				pairingStatus &= ~MICROBIT_BLE_PAIR_REQUEST;
				pairingStatus |= MICROBIT_BLE_PAIR_PASSCODE;
			}
		}

		if (pairingStatus & MICROBIT_BLE_PAIR_PASSCODE)
		{
			timeInPairingMode = 0;
			display.setBrightness(255);
			for (int i=0; i<passKey.length(); i++)
			{
				display.image.print(passKey.charAt(i),0,0);
				fiber_sleep(800);
				display.clear();
				fiber_sleep(200);

				if (pairingStatus & MICROBIT_BLE_PAIR_COMPLETE)
					break;
			}

			fiber_sleep(1000);
		}

		if (pairingStatus & MICROBIT_BLE_PAIR_COMPLETE)
		{
			if (pairingStatus & MICROBIT_BLE_PAIR_SUCCESSFUL)
			{
				MicroBitImage tick("0,0,0,0,0\n0,0,0,0,255\n0,0,0,255,0\n255,0,255,0,0\n0,255,0,0,0\n");
				display.print(tick,0,0,0);
                fiber_sleep(15000);
		        timeInPairingMode = MICROBIT_BLE_PAIRING_TIMEOUT * 30;

                /*
                 * Disabled, as the API to return the number of active bonds is not reliable at present...
                 *
                display.clear();
                ManagedString c(getBondCount());
                ManagedString c2("/");
                ManagedString c3(MICROBIT_BLE_MAXIMUM_BONDS);
                ManagedString c4("USED");

                display.scroll(c+c2+c3+c4);
                *
                *
                */
			}
			else
			{
				MicroBitImage cross("255,0,0,0,255\n0,255,0,255,0\n0,0,255,0,0\n0,255,0,255,0\n255,0,0,0,255\n");
				display.print(cross,0,0,0);
			}
		}

		fiber_sleep(100);
		timeInPairingMode++;

		if (timeInPairingMode >= MICROBIT_BLE_PAIRING_TIMEOUT * 30)
			microbit_reset();
	}
}
Example #18
0
/* a fiber sleeps then gives a semaphore */
static void test_fiber_give_timeout(int sem, int timeout)
{
	fiber_sleep((int32_t)timeout);
	nano_fiber_sem_give((struct nano_sem *)sem);
}
/**
 * @brief Summary data printer fiber
 *
 * @details Print the summary data of the context switch events
 * and the total dropped event ocurred.
 *
 * @return No return value.
 */
void summary_data_printer(void)
{
	int i;

	while (1) {
		/* print task data */
		PRINTF("\x1b[1;32HFork manager task");
		if (forks_available) {
			PRINTF("\x1b[2;32HForks : free to use");
		} else {
			PRINTF("\x1b[2;32HForks : all taken  ");
		}

#ifndef CONFIG_NANOKERNEL
		/* Due to fiber are not pre-emptive, the busy_task_entry thread won't
		 * run as a fiber in nanokernel-only system, because it would affect
		 * the visualization of the sample and the collection of the data
		 * while running busy.
		 */
		PRINTF("\x1b[4;32HWorker task");
		if (is_busy_task_awake) {
			PRINTF("\x1b[5;32HState : BUSY");
			PRINTF("\x1b[6;32H(Prevent the system going idle)");
		} else {
			PRINTF("\x1b[5;32HState : IDLE");
			PRINTF("\x1b[6;32H                               ");
		}
#endif

		/* print general data */
		PRINTF("\x1b[8;1HGENERAL DATA");
		PRINTF("\x1b[9;1H------------");

		PRINTF("\x1b[10;1HSystem tick count : %d    ", sys_tick_get_32());

		/* print dropped event counter */
		PRINTF("\x1b[11;1HDropped events #  : %d   ", total_dropped_counter);

		/* Print context switch event data */
		PRINTF("\x1b[13;1HCONTEXT SWITCH EVENT DATA");
		PRINTF("\x1b[14;1H-------------------------");
		PRINTF("\x1b[15;1HThread ID   Switches");
		for (i = 0; i < MAX_BUFFER_CONTEXT_DATA; i++) {
			if (context_switch_summary_data[i].thread_id != 0) {
				print_context_data(context_switch_summary_data[i].thread_id,
					context_switch_summary_data[i].count,
					context_switch_summary_data[i].last_time_executed, i);
			}
		}

		/* Print sleep event data */
		PRINTF("\x1b[8;32HSLEEP EVENT DATA");
		PRINTF("\x1b[9;32H----------------");
		PRINTF("\x1b[10;32HLast sleep event received");
		if (sleep_event_data.last_time_slept > 0) {
			PRINTF("\x1b[11;32HExit cause : irq #%u   ",
				sleep_event_data.awake_cause);
			PRINTF("\x1b[12;32HAt tick    : %u        ",
				sleep_event_data.last_time_slept);
			PRINTF("\x1b[13;32HDuration   : %u ticks     ",
				sleep_event_data.last_duration);
		}

		/* Print interrupt event data */
		PRINTF("\x1b[15;32HINTERRUPT EVENT DATA");
		PRINTF("\x1b[16;32H--------------------");
		PRINTF("\x1b[17;32HInterrupt counters");

		int line = 0;

		for (i = 0; i < 255; i++) {
			if (interrupt_counters[i] > 0) {
				PRINTF("\x1b[%d;%dHirq #%d : %d times", 18 + line, 32, i,
					interrupt_counters[i]);
				line++;
			}
		}

#ifdef CONFIG_MICROKERNEL
		/* Print task monitor status data */
		PRINTF("\x1b[1;64HTASK MONITOR STATUS DATA");
		PRINTF("\x1b[2;64H-------------------------");
		PRINTF("\x1b[3;64HEvento\tTimestamp\tTaskId\tData");
		for (i = 0; i < MAX_BUFFER_CONTEXT_DATA; i++) {
			if (tmon_summary_data[i].timestamp != 0) {
				print_tmon_status_data(i);
			}
		}
#endif

		/* Sleep */
		fiber_sleep(50);
	}
}