~ruther/uni-mam-arm

ref: 54e9f8d2af25b11710e86886f09b07975bd3e9cc uni-mam-arm/arm07/src/buffered_peripheral.c -rw-r--r-- 2.3 KiB
54e9f8d2 — Rutherther feat(arm07): implement most 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "buffered_peripheral.h"
#include <stdlib.h>
#include <string.h>

void buffered_transceiver_init(buffered_transceiver_t *transceiver,
                               queue_t *rx_queue, queue_t *tx_queue,
                               void *peripheral, buffered_transceiver_vtable_t vtable) {
  transceiver->rx_queue = rx_queue;
  transceiver->tx_queue = tx_queue;
  transceiver->peripheral = peripheral;
  transceiver->vtable = vtable;
}

uint16_t buffered_transceiver_transmit(buffered_transceiver_t *transceiver,
                                            void *buffer, uint16_t size) {
  uint16_t sent = 0;

  if (size == 0) {
    size = strlen((char*)buffer);
  }

  while (sent < size && queue_space(transceiver->tx_queue) > 0) {
    queue_enqueue(transceiver->tx_queue, buffer + sent * transceiver->tx_queue->element_size);
    sent++;
  }

  buffered_transceiver_trigger_transmit(transceiver, 1);

  return sent;
}

uint16_t buffered_transceiver_receive(buffered_transceiver_t *transceiver,
                                      void *buffer, uint16_t max_size) {
  // Get all data from buffer
  buffered_transceiver_trigger_receive(transceiver, 1);
  uint16_t received = 0;

  while (received < max_size && queue_count(transceiver->rx_queue) > 0) {
    queue_dequeue_safely(transceiver->rx_queue, buffer + received*transceiver->rx_queue->element_size);
    received++;
  }

  return received;
}

void buffered_transceiver_trigger_receive(buffered_transceiver_t *transceiver, uint16_t size) {
  void* element = alloca(transceiver->rx_queue->element_size);

  while (transceiver->vtable.can_receive(transceiver->peripheral) > 0 && queue_space(transceiver->rx_queue) > 0) {
    uint16_t received = transceiver->vtable.receive(transceiver->peripheral, element, 1);

    if (received > 0) {
      queue_enqueue(transceiver->rx_queue, element);
    }
  }
}

bool buffered_transceiver_trigger_transmit(buffered_transceiver_t *transceiver,
                                           uint16_t size) {
  while (transceiver->vtable.can_transmit(transceiver->peripheral) &&
         queue_count(transceiver->tx_queue) > 0) {
    void* data = alloca(transceiver->tx_queue->element_size);
    queue_dequeue_safely(transceiver->tx_queue, data);
    transceiver->vtable.transmit(transceiver->peripheral, data, 1);
    return true;
  }

  return false;
}
Do not follow this link