コード例 #1
0
/**
  * A way of dynamically configuring the serial instance to use pins other than USBTX and USBRX.
  *
  * @param tx the new transmission pin.
  *
  * @param rx the new reception pin.
  *
  * @return MICROBIT_SERIAL_IN_USE if another fiber is currently transmitting or receiving, otherwise MICROBIT_OK.
  */
int MicroBitSerial::redirect(PinName tx, PinName rx)
{
    if(txInUse() || rxInUse())
        return MICROBIT_SERIAL_IN_USE;

    lockTx();
    lockRx();

    if(txBufferedSize() > 0)
        detach(Serial::TxIrq);

    detach(Serial::RxIrq);

    serial_free(&_serial);
    serial_init(&_serial, tx, rx);

    attach(this, &MicroBitSerial::dataReceived, Serial::RxIrq);

    if(txBufferedSize() > 0)
        attach(this, &MicroBitSerial::dataWritten, Serial::TxIrq);

    this->baud(this->baudrate);

    unlockRx();
    unlockTx();

    return MICROBIT_OK;
}
コード例 #2
0
/**
  * 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);
}
コード例 #3
0
/**
  * Copies characters into the buffer used for Transmitting to the central device.
  *
  * @param buf a buffer containing length number of bytes.
  * @param length the size of the buffer.
  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
  *        gives a different behaviour:
  *
  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
  *                    and return control to the user.
  *
  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
  *
  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
  *                         given characters have been received by the connected
  *                         device.
  *
  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
  *         no connected device, or the connected device has not enabled indications.
  */
int MicroBitUARTService::send(const uint8_t *buf, int length, MicroBitSerialMode mode)
{
    if(length < 1 || mode == SYNC_SPINWAIT)
        return MICROBIT_INVALID_PARAMETER;

    bool updatesEnabled = false;

    ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);

    if(!ble.getGapState().connected && !updatesEnabled)
        return MICROBIT_NOT_SUPPORTED;

    int bytesWritten = 0;

    while(bytesWritten < length && ble.getGapState().connected && updatesEnabled)
    {
        for(int bufferIterator = bytesWritten; bufferIterator < length; bufferIterator++)
        {
            int nextHead = (txBufferHead + 1) % txBufferSize;

            if(nextHead != txBufferTail)
            {
                txBuffer[txBufferHead] = buf[bufferIterator];

                txBufferHead = nextHead;

                bytesWritten++;
            }
        }

        int size = txBufferedSize();

        uint8_t temp[size];

        memclr(&temp, size);

        circularCopy(txBuffer, txBufferSize, temp, txBufferTail, txBufferHead);


        if(mode == SYNC_SLEEP)
            fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);

        ble.gattServer().write(txCharacteristic->getValueAttribute().getHandle(), temp, size);

        if(mode == SYNC_SLEEP)
            schedule();
        else
            break;

        ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
    }

    return bytesWritten;
}