mbed API for Raspberry Pi boards.
mbedPi
This is an attempt to implement a limited number of mbed APIs for Raspberry Pi single-board computers. The project was inspired by and based on the arduPi library developed for the Arduino by Cooking Hacks .
Specifications
- Chip: Broadcom BCM2836 SoC
- Core architecture: Quad-core ARM Cortex-A7
- CPU frequency: 900 MHz
- GPU: Dual Core VideoCore IV® Multimedia Co-Processor
- Memory: 1GB LPDDR2
- Operating System: Boots from Micro SD card, running a version of the Linux operating system
- Power: Micro USB socket 5V, 2A
Connectors
- Ethernet: 10/100 BaseT Ethernet socket
- Video Output: HDMI (rev 1.3 & 1.4)
- Audio Output: 3.5mm jack, HDMI
- USB: 4 x USB 2.0 Connector
- GPIO Connector: 40-pin 2.54 mm (100 mil) expansion header: 2x20 strip providing 27 GPIO pins as well as +3.3 V, +5 V and GND supply lines
- Camera Connector: 15-pin MIPI Camera Serial Interface (CSI-2)
- JTAG: Not populated
- Display Connector: Display Serial Interface (DSI) 15 way flat flex cable connector with two data lanes and a clock lane
- Memory Card Slot: Micro SDIO
GPIO connector pinout
Information
Only the labels printed in blue/white or green/white (i.e. p3, gpio2 ...) must be used in your code. The other labels are given as information (alternate-functions, power pins, ...).
Building programs for the Raspberry Pi with mbedPi
I use Qt Creator for development, however you can use any other IDE available on the Raspberry Pi (e.g. Geany) if you like. For a quick try:
- Install Qt and the Qt Creator onto your Raspberry Pi. Then create a new "Blinky" Plain non-Qt C++ Project as follows:
- Change the main code as below:
main.cpp
#include "mbedPi.h" int main() { DigitalOut myled(p7); while(1) { myled = 1; // LED is ON wait(0.2); // 200 ms myled = 0; // LED is OFF wait(1.0); // 1 sec printf("Blink\r\n"); } }
- Copy the mbedPi.zip file into your project's folder and unzip.
- Add the mbedPi.h and mbedPi.cpp files to your project by right clicking on the "Blinky" project and then clicking on the "Add Existing Files..." option in the local menu:
- Double click on Blinky.pro to open it for editing and add new libraries by inserting a new line as follows:
- Compile the project.
- Connect an LED through a 1k resistor to pin 7 and the ground on the Raspberry Pi GPIO connector.
- Run the binary as sudo (sudo ./Blinky) and you should see the LED blinking.
- Press Ctrl+c to stop running the application.
source/Serial.cpp@1:1f2d9982fa8c, 22 months ago (annotated)
- Committer:
- hudakz
- Date:
- Tue Dec 20 12:08:07 2022 +0000
- Revision:
- 1:1f2d9982fa8c
mbed API for Raspberry Pi boards equipped with BCM2836 SoC.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hudakz | 1:1f2d9982fa8c | 1 | #include "mbed.h" |
hudakz | 1:1f2d9982fa8c | 2 | #include <stdarg.h> |
hudakz | 1:1f2d9982fa8c | 3 | |
hudakz | 1:1f2d9982fa8c | 4 | |
hudakz | 1:1f2d9982fa8c | 5 | /** |
hudakz | 1:1f2d9982fa8c | 6 | * @brief |
hudakz | 1:1f2d9982fa8c | 7 | * @note |
hudakz | 1:1f2d9982fa8c | 8 | * @param |
hudakz | 1:1f2d9982fa8c | 9 | * @retval |
hudakz | 1:1f2d9982fa8c | 10 | */ |
hudakz | 1:1f2d9982fa8c | 11 | Serial::Serial() |
hudakz | 1:1f2d9982fa8c | 12 | { |
hudakz | 1:1f2d9982fa8c | 13 | //if((tx == gpio14) && (tx == gpio15)) { |
hudakz | 1:1f2d9982fa8c | 14 | |
hudakz | 1:1f2d9982fa8c | 15 | REV = getBoardRev(); |
hudakz | 1:1f2d9982fa8c | 16 | serialPort = "/dev/ttyAMA0"; |
hudakz | 1:1f2d9982fa8c | 17 | timeOut = 1000; |
hudakz | 1:1f2d9982fa8c | 18 | |
hudakz | 1:1f2d9982fa8c | 19 | //baud(9600); |
hudakz | 1:1f2d9982fa8c | 20 | //} |
hudakz | 1:1f2d9982fa8c | 21 | } |
hudakz | 1:1f2d9982fa8c | 22 | |
hudakz | 1:1f2d9982fa8c | 23 | /** |
hudakz | 1:1f2d9982fa8c | 24 | * @brief |
hudakz | 1:1f2d9982fa8c | 25 | * @note |
hudakz | 1:1f2d9982fa8c | 26 | * @param |
hudakz | 1:1f2d9982fa8c | 27 | * @retval |
hudakz | 1:1f2d9982fa8c | 28 | */ |
hudakz | 1:1f2d9982fa8c | 29 | void Serial::baud(int baudrate) |
hudakz | 1:1f2d9982fa8c | 30 | { |
hudakz | 1:1f2d9982fa8c | 31 | switch (baudrate) { |
hudakz | 1:1f2d9982fa8c | 32 | case 50: |
hudakz | 1:1f2d9982fa8c | 33 | speed = B50; |
hudakz | 1:1f2d9982fa8c | 34 | break; |
hudakz | 1:1f2d9982fa8c | 35 | |
hudakz | 1:1f2d9982fa8c | 36 | case 75: |
hudakz | 1:1f2d9982fa8c | 37 | speed = B75; |
hudakz | 1:1f2d9982fa8c | 38 | break; |
hudakz | 1:1f2d9982fa8c | 39 | |
hudakz | 1:1f2d9982fa8c | 40 | case 110: |
hudakz | 1:1f2d9982fa8c | 41 | speed = B110; |
hudakz | 1:1f2d9982fa8c | 42 | break; |
hudakz | 1:1f2d9982fa8c | 43 | |
hudakz | 1:1f2d9982fa8c | 44 | case 134: |
hudakz | 1:1f2d9982fa8c | 45 | speed = B134; |
hudakz | 1:1f2d9982fa8c | 46 | break; |
hudakz | 1:1f2d9982fa8c | 47 | |
hudakz | 1:1f2d9982fa8c | 48 | case 150: |
hudakz | 1:1f2d9982fa8c | 49 | speed = B150; |
hudakz | 1:1f2d9982fa8c | 50 | break; |
hudakz | 1:1f2d9982fa8c | 51 | |
hudakz | 1:1f2d9982fa8c | 52 | case 200: |
hudakz | 1:1f2d9982fa8c | 53 | speed = B200; |
hudakz | 1:1f2d9982fa8c | 54 | break; |
hudakz | 1:1f2d9982fa8c | 55 | |
hudakz | 1:1f2d9982fa8c | 56 | case 300: |
hudakz | 1:1f2d9982fa8c | 57 | speed = B300; |
hudakz | 1:1f2d9982fa8c | 58 | break; |
hudakz | 1:1f2d9982fa8c | 59 | |
hudakz | 1:1f2d9982fa8c | 60 | case 600: |
hudakz | 1:1f2d9982fa8c | 61 | speed = B600; |
hudakz | 1:1f2d9982fa8c | 62 | break; |
hudakz | 1:1f2d9982fa8c | 63 | |
hudakz | 1:1f2d9982fa8c | 64 | case 1200: |
hudakz | 1:1f2d9982fa8c | 65 | speed = B1200; |
hudakz | 1:1f2d9982fa8c | 66 | break; |
hudakz | 1:1f2d9982fa8c | 67 | |
hudakz | 1:1f2d9982fa8c | 68 | case 1800: |
hudakz | 1:1f2d9982fa8c | 69 | speed = B1800; |
hudakz | 1:1f2d9982fa8c | 70 | break; |
hudakz | 1:1f2d9982fa8c | 71 | |
hudakz | 1:1f2d9982fa8c | 72 | case 2400: |
hudakz | 1:1f2d9982fa8c | 73 | speed = B2400; |
hudakz | 1:1f2d9982fa8c | 74 | break; |
hudakz | 1:1f2d9982fa8c | 75 | |
hudakz | 1:1f2d9982fa8c | 76 | case 9600: |
hudakz | 1:1f2d9982fa8c | 77 | speed = B9600; |
hudakz | 1:1f2d9982fa8c | 78 | break; |
hudakz | 1:1f2d9982fa8c | 79 | |
hudakz | 1:1f2d9982fa8c | 80 | case 19200: |
hudakz | 1:1f2d9982fa8c | 81 | speed = B19200; |
hudakz | 1:1f2d9982fa8c | 82 | break; |
hudakz | 1:1f2d9982fa8c | 83 | |
hudakz | 1:1f2d9982fa8c | 84 | case 38400: |
hudakz | 1:1f2d9982fa8c | 85 | speed = B38400; |
hudakz | 1:1f2d9982fa8c | 86 | break; |
hudakz | 1:1f2d9982fa8c | 87 | |
hudakz | 1:1f2d9982fa8c | 88 | case 57600: |
hudakz | 1:1f2d9982fa8c | 89 | speed = B57600; |
hudakz | 1:1f2d9982fa8c | 90 | break; |
hudakz | 1:1f2d9982fa8c | 91 | |
hudakz | 1:1f2d9982fa8c | 92 | case 115200: |
hudakz | 1:1f2d9982fa8c | 93 | speed = B115200; |
hudakz | 1:1f2d9982fa8c | 94 | break; |
hudakz | 1:1f2d9982fa8c | 95 | |
hudakz | 1:1f2d9982fa8c | 96 | default: |
hudakz | 1:1f2d9982fa8c | 97 | speed = B230400; |
hudakz | 1:1f2d9982fa8c | 98 | break; |
hudakz | 1:1f2d9982fa8c | 99 | } |
hudakz | 1:1f2d9982fa8c | 100 | |
hudakz | 1:1f2d9982fa8c | 101 | if ((sd = open(serialPort, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) { |
hudakz | 1:1f2d9982fa8c | 102 | fprintf(stderr, "Unable to open the serial port %s - \n", serialPort); |
hudakz | 1:1f2d9982fa8c | 103 | exit(-1); |
hudakz | 1:1f2d9982fa8c | 104 | } |
hudakz | 1:1f2d9982fa8c | 105 | |
hudakz | 1:1f2d9982fa8c | 106 | fcntl(sd, F_SETFL, O_RDWR); |
hudakz | 1:1f2d9982fa8c | 107 | |
hudakz | 1:1f2d9982fa8c | 108 | tcgetattr(sd, &options); |
hudakz | 1:1f2d9982fa8c | 109 | cfmakeraw(&options); |
hudakz | 1:1f2d9982fa8c | 110 | cfsetispeed(&options, speed); |
hudakz | 1:1f2d9982fa8c | 111 | cfsetospeed(&options, speed); |
hudakz | 1:1f2d9982fa8c | 112 | |
hudakz | 1:1f2d9982fa8c | 113 | options.c_cflag |= (CLOCAL | CREAD); |
hudakz | 1:1f2d9982fa8c | 114 | options.c_cflag &= ~PARENB; |
hudakz | 1:1f2d9982fa8c | 115 | options.c_cflag &= ~CSTOPB; |
hudakz | 1:1f2d9982fa8c | 116 | options.c_cflag &= ~CSIZE; |
hudakz | 1:1f2d9982fa8c | 117 | options.c_cflag |= CS8; |
hudakz | 1:1f2d9982fa8c | 118 | options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); |
hudakz | 1:1f2d9982fa8c | 119 | options.c_oflag &= ~OPOST; |
hudakz | 1:1f2d9982fa8c | 120 | |
hudakz | 1:1f2d9982fa8c | 121 | tcsetattr(sd, TCSANOW, &options); |
hudakz | 1:1f2d9982fa8c | 122 | |
hudakz | 1:1f2d9982fa8c | 123 | ioctl(sd, TIOCMGET, &status); |
hudakz | 1:1f2d9982fa8c | 124 | |
hudakz | 1:1f2d9982fa8c | 125 | status |= TIOCM_DTR; |
hudakz | 1:1f2d9982fa8c | 126 | status |= TIOCM_RTS; |
hudakz | 1:1f2d9982fa8c | 127 | |
hudakz | 1:1f2d9982fa8c | 128 | ioctl(sd, TIOCMSET, &status); |
hudakz | 1:1f2d9982fa8c | 129 | |
hudakz | 1:1f2d9982fa8c | 130 | unistd::usleep(10000); |
hudakz | 1:1f2d9982fa8c | 131 | } |
hudakz | 1:1f2d9982fa8c | 132 | |
hudakz | 1:1f2d9982fa8c | 133 | /** |
hudakz | 1:1f2d9982fa8c | 134 | * @brief |
hudakz | 1:1f2d9982fa8c | 135 | * @note |
hudakz | 1:1f2d9982fa8c | 136 | * @param |
hudakz | 1:1f2d9982fa8c | 137 | * @retval |
hudakz | 1:1f2d9982fa8c | 138 | */ |
hudakz | 1:1f2d9982fa8c | 139 | void Serial::printf(const char* format, ...) |
hudakz | 1:1f2d9982fa8c | 140 | { |
hudakz | 1:1f2d9982fa8c | 141 | char* buf; |
hudakz | 1:1f2d9982fa8c | 142 | va_list args; |
hudakz | 1:1f2d9982fa8c | 143 | |
hudakz | 1:1f2d9982fa8c | 144 | va_start(args, format); |
hudakz | 1:1f2d9982fa8c | 145 | vasprintf(&buf, format, args); |
hudakz | 1:1f2d9982fa8c | 146 | va_end(args); |
hudakz | 1:1f2d9982fa8c | 147 | unistd::write(sd, buf, strlen(buf)); |
hudakz | 1:1f2d9982fa8c | 148 | free(buf); |
hudakz | 1:1f2d9982fa8c | 149 | } |
hudakz | 1:1f2d9982fa8c | 150 | |
hudakz | 1:1f2d9982fa8c | 151 | /* Writes binary data to the serial port. This data is sent as a byte |
hudakz | 1:1f2d9982fa8c | 152 | * Returns: number of bytes written */ |
hudakz | 1:1f2d9982fa8c | 153 | int Serial::write(uint8_t message) |
hudakz | 1:1f2d9982fa8c | 154 | { |
hudakz | 1:1f2d9982fa8c | 155 | unistd::write(sd, &message, 1); |
hudakz | 1:1f2d9982fa8c | 156 | return 1; |
hudakz | 1:1f2d9982fa8c | 157 | } |
hudakz | 1:1f2d9982fa8c | 158 | |
hudakz | 1:1f2d9982fa8c | 159 | /* Writes binary data to the serial port. This data is sent as a series |
hudakz | 1:1f2d9982fa8c | 160 | * of bytes |
hudakz | 1:1f2d9982fa8c | 161 | * Returns: number of bytes written */ |
hudakz | 1:1f2d9982fa8c | 162 | int Serial::write(const char* message) |
hudakz | 1:1f2d9982fa8c | 163 | { |
hudakz | 1:1f2d9982fa8c | 164 | int len = strlen(message); |
hudakz | 1:1f2d9982fa8c | 165 | unistd::write(sd, &message, len); |
hudakz | 1:1f2d9982fa8c | 166 | return len; |
hudakz | 1:1f2d9982fa8c | 167 | } |
hudakz | 1:1f2d9982fa8c | 168 | |
hudakz | 1:1f2d9982fa8c | 169 | /* Writes binary data to the serial port. This data is sent as a series |
hudakz | 1:1f2d9982fa8c | 170 | * of bytes placed in an buffer. It needs the length of the buffer |
hudakz | 1:1f2d9982fa8c | 171 | * Returns: number of bytes written */ |
hudakz | 1:1f2d9982fa8c | 172 | int Serial::write(char* message, int size) |
hudakz | 1:1f2d9982fa8c | 173 | { |
hudakz | 1:1f2d9982fa8c | 174 | unistd::write(sd, message, size); |
hudakz | 1:1f2d9982fa8c | 175 | return size; |
hudakz | 1:1f2d9982fa8c | 176 | } |
hudakz | 1:1f2d9982fa8c | 177 | |
hudakz | 1:1f2d9982fa8c | 178 | /** |
hudakz | 1:1f2d9982fa8c | 179 | * @brief |
hudakz | 1:1f2d9982fa8c | 180 | * @note |
hudakz | 1:1f2d9982fa8c | 181 | * @param |
hudakz | 1:1f2d9982fa8c | 182 | * @retval |
hudakz | 1:1f2d9982fa8c | 183 | */ |
hudakz | 1:1f2d9982fa8c | 184 | int Serial::readable() |
hudakz | 1:1f2d9982fa8c | 185 | { |
hudakz | 1:1f2d9982fa8c | 186 | int nbytes = 0; |
hudakz | 1:1f2d9982fa8c | 187 | if (ioctl(sd, FIONREAD, &nbytes) < 0) { |
hudakz | 1:1f2d9982fa8c | 188 | fprintf(stderr, "Failed to get byte count on serial.\n"); |
hudakz | 1:1f2d9982fa8c | 189 | exit(-1); |
hudakz | 1:1f2d9982fa8c | 190 | } |
hudakz | 1:1f2d9982fa8c | 191 | |
hudakz | 1:1f2d9982fa8c | 192 | return(nbytes > 0 ? 1 : 0); |
hudakz | 1:1f2d9982fa8c | 193 | } |
hudakz | 1:1f2d9982fa8c | 194 | |
hudakz | 1:1f2d9982fa8c | 195 | /* Reads 1 byte of incoming serial data |
hudakz | 1:1f2d9982fa8c | 196 | * Returns: first byte of incoming serial data available */ |
hudakz | 1:1f2d9982fa8c | 197 | char Serial::read() |
hudakz | 1:1f2d9982fa8c | 198 | { |
hudakz | 1:1f2d9982fa8c | 199 | unistd::read(sd, &c, 1); |
hudakz | 1:1f2d9982fa8c | 200 | return c; |
hudakz | 1:1f2d9982fa8c | 201 | } |
hudakz | 1:1f2d9982fa8c | 202 | |
hudakz | 1:1f2d9982fa8c | 203 | /* Reads characters from th serial port into a buffer. The function |
hudakz | 1:1f2d9982fa8c | 204 | * terminates if the determined length has been read, or it times out |
hudakz | 1:1f2d9982fa8c | 205 | * Returns: number of bytes readed */ |
hudakz | 1:1f2d9982fa8c | 206 | int Serial::readBytes(char message[], int size) |
hudakz | 1:1f2d9982fa8c | 207 | { |
hudakz | 1:1f2d9982fa8c | 208 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); |
hudakz | 1:1f2d9982fa8c | 209 | |
hudakz | 1:1f2d9982fa8c | 210 | int count; |
hudakz | 1:1f2d9982fa8c | 211 | for (count = 0; count < size; count++) { |
hudakz | 1:1f2d9982fa8c | 212 | if (readable()) |
hudakz | 1:1f2d9982fa8c | 213 | unistd::read(sd, &message[count], 1); |
hudakz | 1:1f2d9982fa8c | 214 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); |
hudakz | 1:1f2d9982fa8c | 215 | |
hudakz | 1:1f2d9982fa8c | 216 | timespec t = timeDiff(time1, time2); |
hudakz | 1:1f2d9982fa8c | 217 | if ((t.tv_nsec / 1000) > timeOut) |
hudakz | 1:1f2d9982fa8c | 218 | break; |
hudakz | 1:1f2d9982fa8c | 219 | } |
hudakz | 1:1f2d9982fa8c | 220 | |
hudakz | 1:1f2d9982fa8c | 221 | return count; |
hudakz | 1:1f2d9982fa8c | 222 | } |
hudakz | 1:1f2d9982fa8c | 223 | |
hudakz | 1:1f2d9982fa8c | 224 | /* Reads characters from the serial buffer into an array. |
hudakz | 1:1f2d9982fa8c | 225 | * The function terminates if the terminator character is detected, |
hudakz | 1:1f2d9982fa8c | 226 | * the determined length has been read, or it times out. |
hudakz | 1:1f2d9982fa8c | 227 | * Returns: number of characters read into the buffer. */ |
hudakz | 1:1f2d9982fa8c | 228 | int Serial::readBytesUntil(char character, char buffer[], int length) |
hudakz | 1:1f2d9982fa8c | 229 | { |
hudakz | 1:1f2d9982fa8c | 230 | char lastReaded = character + 1; //Just to make lastReaded != character |
hudakz | 1:1f2d9982fa8c | 231 | int count = 0; |
hudakz | 1:1f2d9982fa8c | 232 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); |
hudakz | 1:1f2d9982fa8c | 233 | while (count != length && lastReaded != character) { |
hudakz | 1:1f2d9982fa8c | 234 | if (readable()) |
hudakz | 1:1f2d9982fa8c | 235 | unistd::read(sd, &buffer[count], 1); |
hudakz | 1:1f2d9982fa8c | 236 | lastReaded = buffer[count]; |
hudakz | 1:1f2d9982fa8c | 237 | count++; |
hudakz | 1:1f2d9982fa8c | 238 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); |
hudakz | 1:1f2d9982fa8c | 239 | |
hudakz | 1:1f2d9982fa8c | 240 | timespec t = timeDiff(time1, time2); |
hudakz | 1:1f2d9982fa8c | 241 | if ((t.tv_nsec / 1000) > timeOut) |
hudakz | 1:1f2d9982fa8c | 242 | break; |
hudakz | 1:1f2d9982fa8c | 243 | } |
hudakz | 1:1f2d9982fa8c | 244 | |
hudakz | 1:1f2d9982fa8c | 245 | return count; |
hudakz | 1:1f2d9982fa8c | 246 | } |
hudakz | 1:1f2d9982fa8c | 247 | |
hudakz | 1:1f2d9982fa8c | 248 | /** |
hudakz | 1:1f2d9982fa8c | 249 | * @brief |
hudakz | 1:1f2d9982fa8c | 250 | * @note |
hudakz | 1:1f2d9982fa8c | 251 | * @param |
hudakz | 1:1f2d9982fa8c | 252 | * @retval |
hudakz | 1:1f2d9982fa8c | 253 | */ |
hudakz | 1:1f2d9982fa8c | 254 | bool Serial::find(const char* target) |
hudakz | 1:1f2d9982fa8c | 255 | { |
hudakz | 1:1f2d9982fa8c | 256 | findUntil(target, NULL); |
hudakz | 1:1f2d9982fa8c | 257 | } |
hudakz | 1:1f2d9982fa8c | 258 | |
hudakz | 1:1f2d9982fa8c | 259 | /* Reads data from the serial buffer until a target string of given length |
hudakz | 1:1f2d9982fa8c | 260 | * or terminator string is found. |
hudakz | 1:1f2d9982fa8c | 261 | * Returns: true if the target string is found, false if it times out */ |
hudakz | 1:1f2d9982fa8c | 262 | bool Serial::findUntil(const char* target, const char* terminal) |
hudakz | 1:1f2d9982fa8c | 263 | { |
hudakz | 1:1f2d9982fa8c | 264 | int index = 0; |
hudakz | 1:1f2d9982fa8c | 265 | int termIndex = 0; |
hudakz | 1:1f2d9982fa8c | 266 | int targetLen = strlen(target); |
hudakz | 1:1f2d9982fa8c | 267 | int termLen = strlen(terminal); |
hudakz | 1:1f2d9982fa8c | 268 | char readed; |
hudakz | 1:1f2d9982fa8c | 269 | timespec t; |
hudakz | 1:1f2d9982fa8c | 270 | |
hudakz | 1:1f2d9982fa8c | 271 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); |
hudakz | 1:1f2d9982fa8c | 272 | |
hudakz | 1:1f2d9982fa8c | 273 | if (*target == 0) |
hudakz | 1:1f2d9982fa8c | 274 | return true; // return true if target is a null string |
hudakz | 1:1f2d9982fa8c | 275 | do |
hudakz | 1:1f2d9982fa8c | 276 | { |
hudakz | 1:1f2d9982fa8c | 277 | if (readable()) { |
hudakz | 1:1f2d9982fa8c | 278 | unistd::read(sd, &readed, 1); |
hudakz | 1:1f2d9982fa8c | 279 | if (readed != target[index]) |
hudakz | 1:1f2d9982fa8c | 280 | index = 0; // reset index if any char does not match |
hudakz | 1:1f2d9982fa8c | 281 | if (readed == target[index]) { |
hudakz | 1:1f2d9982fa8c | 282 | if (++index >= targetLen) { |
hudakz | 1:1f2d9982fa8c | 283 | |
hudakz | 1:1f2d9982fa8c | 284 | // return true if all chars in the target match |
hudakz | 1:1f2d9982fa8c | 285 | return true; |
hudakz | 1:1f2d9982fa8c | 286 | } |
hudakz | 1:1f2d9982fa8c | 287 | } |
hudakz | 1:1f2d9982fa8c | 288 | |
hudakz | 1:1f2d9982fa8c | 289 | if (termLen > 0 && c == terminal[termIndex]) { |
hudakz | 1:1f2d9982fa8c | 290 | if (++termIndex >= termLen) |
hudakz | 1:1f2d9982fa8c | 291 | return false; // return false if terminate string found before target string |
hudakz | 1:1f2d9982fa8c | 292 | } |
hudakz | 1:1f2d9982fa8c | 293 | else { |
hudakz | 1:1f2d9982fa8c | 294 | termIndex = 0; |
hudakz | 1:1f2d9982fa8c | 295 | } |
hudakz | 1:1f2d9982fa8c | 296 | } |
hudakz | 1:1f2d9982fa8c | 297 | |
hudakz | 1:1f2d9982fa8c | 298 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); |
hudakz | 1:1f2d9982fa8c | 299 | t = timeDiff(time1, time2); |
hudakz | 1:1f2d9982fa8c | 300 | } while ((t.tv_nsec / 1000) <= timeOut); |
hudakz | 1:1f2d9982fa8c | 301 | |
hudakz | 1:1f2d9982fa8c | 302 | return false; |
hudakz | 1:1f2d9982fa8c | 303 | } |
hudakz | 1:1f2d9982fa8c | 304 | |
hudakz | 1:1f2d9982fa8c | 305 | /* returns the first valid (long) integer value from the current position. |
hudakz | 1:1f2d9982fa8c | 306 | * initial characters that are not digits (or the minus sign) are skipped |
hudakz | 1:1f2d9982fa8c | 307 | * function is terminated by the first character that is not a digit. */ |
hudakz | 1:1f2d9982fa8c | 308 | long Serial::parseInt() |
hudakz | 1:1f2d9982fa8c | 309 | { |
hudakz | 1:1f2d9982fa8c | 310 | bool isNegative = false; |
hudakz | 1:1f2d9982fa8c | 311 | long value = 0; |
hudakz | 1:1f2d9982fa8c | 312 | char c; |
hudakz | 1:1f2d9982fa8c | 313 | |
hudakz | 1:1f2d9982fa8c | 314 | //Skip characters until a number or - sign found |
hudakz | 1:1f2d9982fa8c | 315 | |
hudakz | 1:1f2d9982fa8c | 316 | do |
hudakz | 1:1f2d9982fa8c | 317 | { |
hudakz | 1:1f2d9982fa8c | 318 | c = peek(); |
hudakz | 1:1f2d9982fa8c | 319 | if (c == '-') |
hudakz | 1:1f2d9982fa8c | 320 | break; |
hudakz | 1:1f2d9982fa8c | 321 | if (c >= '0' && c <= '9') |
hudakz | 1:1f2d9982fa8c | 322 | break; |
hudakz | 1:1f2d9982fa8c | 323 | unistd::read(sd, &c, 1); // discard non-numeric |
hudakz | 1:1f2d9982fa8c | 324 | } while (1); |
hudakz | 1:1f2d9982fa8c | 325 | |
hudakz | 1:1f2d9982fa8c | 326 | do |
hudakz | 1:1f2d9982fa8c | 327 | { |
hudakz | 1:1f2d9982fa8c | 328 | if (c == '-') |
hudakz | 1:1f2d9982fa8c | 329 | isNegative = true; |
hudakz | 1:1f2d9982fa8c | 330 | else |
hudakz | 1:1f2d9982fa8c | 331 | if (c >= '0' && c <= '9') // is c a digit? |
hudakz | 1:1f2d9982fa8c | 332 | value = value * 10 + c - '0'; |
hudakz | 1:1f2d9982fa8c | 333 | unistd::read(sd, &c, 1); // consume the character we got with peek |
hudakz | 1:1f2d9982fa8c | 334 | c = peek(); |
hudakz | 1:1f2d9982fa8c | 335 | } while (c >= '0' && c <= '9'); |
hudakz | 1:1f2d9982fa8c | 336 | |
hudakz | 1:1f2d9982fa8c | 337 | if (isNegative) |
hudakz | 1:1f2d9982fa8c | 338 | value = -value; |
hudakz | 1:1f2d9982fa8c | 339 | return value; |
hudakz | 1:1f2d9982fa8c | 340 | } |
hudakz | 1:1f2d9982fa8c | 341 | |
hudakz | 1:1f2d9982fa8c | 342 | /** |
hudakz | 1:1f2d9982fa8c | 343 | * @brief |
hudakz | 1:1f2d9982fa8c | 344 | * @note |
hudakz | 1:1f2d9982fa8c | 345 | * @param |
hudakz | 1:1f2d9982fa8c | 346 | * @retval |
hudakz | 1:1f2d9982fa8c | 347 | */ |
hudakz | 1:1f2d9982fa8c | 348 | float Serial::parseFloat() |
hudakz | 1:1f2d9982fa8c | 349 | { |
hudakz | 1:1f2d9982fa8c | 350 | boolean isNegative = false; |
hudakz | 1:1f2d9982fa8c | 351 | boolean isFraction = false; |
hudakz | 1:1f2d9982fa8c | 352 | long value = 0; |
hudakz | 1:1f2d9982fa8c | 353 | char c; |
hudakz | 1:1f2d9982fa8c | 354 | float fraction = 1.0; |
hudakz | 1:1f2d9982fa8c | 355 | |
hudakz | 1:1f2d9982fa8c | 356 | //Skip characters until a number or - sign found |
hudakz | 1:1f2d9982fa8c | 357 | |
hudakz | 1:1f2d9982fa8c | 358 | do |
hudakz | 1:1f2d9982fa8c | 359 | { |
hudakz | 1:1f2d9982fa8c | 360 | c = peek(); |
hudakz | 1:1f2d9982fa8c | 361 | if (c == '-') |
hudakz | 1:1f2d9982fa8c | 362 | break; |
hudakz | 1:1f2d9982fa8c | 363 | if (c >= '0' && c <= '9') |
hudakz | 1:1f2d9982fa8c | 364 | break; |
hudakz | 1:1f2d9982fa8c | 365 | unistd::read(sd, &c, 1); // discard non-numeric |
hudakz | 1:1f2d9982fa8c | 366 | } while (1); |
hudakz | 1:1f2d9982fa8c | 367 | |
hudakz | 1:1f2d9982fa8c | 368 | do |
hudakz | 1:1f2d9982fa8c | 369 | { |
hudakz | 1:1f2d9982fa8c | 370 | if (c == '-') |
hudakz | 1:1f2d9982fa8c | 371 | isNegative = true; |
hudakz | 1:1f2d9982fa8c | 372 | else |
hudakz | 1:1f2d9982fa8c | 373 | if (c == '.') |
hudakz | 1:1f2d9982fa8c | 374 | isFraction = true; |
hudakz | 1:1f2d9982fa8c | 375 | else |
hudakz | 1:1f2d9982fa8c | 376 | if (c >= '0' && c <= '9') { |
hudakz | 1:1f2d9982fa8c | 377 | |
hudakz | 1:1f2d9982fa8c | 378 | // is c a digit? |
hudakz | 1:1f2d9982fa8c | 379 | value = value * 10 + c - '0'; |
hudakz | 1:1f2d9982fa8c | 380 | if (isFraction) |
hudakz | 1:1f2d9982fa8c | 381 | fraction *= 0.1; |
hudakz | 1:1f2d9982fa8c | 382 | } |
hudakz | 1:1f2d9982fa8c | 383 | |
hudakz | 1:1f2d9982fa8c | 384 | unistd::read(sd, &c, 1); // consume the character we got with peek |
hudakz | 1:1f2d9982fa8c | 385 | c = peek(); |
hudakz | 1:1f2d9982fa8c | 386 | } while ((c >= '0' && c <= '9') || (c == '.' && isFraction == false)); |
hudakz | 1:1f2d9982fa8c | 387 | |
hudakz | 1:1f2d9982fa8c | 388 | if (isNegative) |
hudakz | 1:1f2d9982fa8c | 389 | value = -value; |
hudakz | 1:1f2d9982fa8c | 390 | if (isFraction) |
hudakz | 1:1f2d9982fa8c | 391 | return value * fraction; |
hudakz | 1:1f2d9982fa8c | 392 | else |
hudakz | 1:1f2d9982fa8c | 393 | return value; |
hudakz | 1:1f2d9982fa8c | 394 | } |
hudakz | 1:1f2d9982fa8c | 395 | |
hudakz | 1:1f2d9982fa8c | 396 | // Returns the next byte (character) of incoming serial data without removing it from the internal serial buffer. |
hudakz | 1:1f2d9982fa8c | 397 | char Serial::peek() |
hudakz | 1:1f2d9982fa8c | 398 | { |
hudakz | 1:1f2d9982fa8c | 399 | //We obtain a pointer to FILE structure from the file descriptor sd |
hudakz | 1:1f2d9982fa8c | 400 | FILE* f = fdopen(sd, "r+"); |
hudakz | 1:1f2d9982fa8c | 401 | |
hudakz | 1:1f2d9982fa8c | 402 | //With a pointer to FILE we can do getc and ungetc |
hudakz | 1:1f2d9982fa8c | 403 | |
hudakz | 1:1f2d9982fa8c | 404 | c = getc(f); |
hudakz | 1:1f2d9982fa8c | 405 | ungetc(c, f); |
hudakz | 1:1f2d9982fa8c | 406 | return c; |
hudakz | 1:1f2d9982fa8c | 407 | } |
hudakz | 1:1f2d9982fa8c | 408 | |
hudakz | 1:1f2d9982fa8c | 409 | // Remove any data remaining on the serial buffer |
hudakz | 1:1f2d9982fa8c | 410 | void Serial::flush() |
hudakz | 1:1f2d9982fa8c | 411 | { |
hudakz | 1:1f2d9982fa8c | 412 | while (readable()) { |
hudakz | 1:1f2d9982fa8c | 413 | unistd::read(sd, &c, 1); |
hudakz | 1:1f2d9982fa8c | 414 | } |
hudakz | 1:1f2d9982fa8c | 415 | } |
hudakz | 1:1f2d9982fa8c | 416 | |
hudakz | 1:1f2d9982fa8c | 417 | /* Sets the maximum milliseconds to wait for serial data when using SerialPI::readBytes() |
hudakz | 1:1f2d9982fa8c | 418 | * The default value is set to 1000 */ |
hudakz | 1:1f2d9982fa8c | 419 | void Serial::setTimeout(long millis) |
hudakz | 1:1f2d9982fa8c | 420 | { |
hudakz | 1:1f2d9982fa8c | 421 | timeOut = millis; |
hudakz | 1:1f2d9982fa8c | 422 | } |
hudakz | 1:1f2d9982fa8c | 423 | |
hudakz | 1:1f2d9982fa8c | 424 | //Closes serial communication |
hudakz | 1:1f2d9982fa8c | 425 | void Serial::close() |
hudakz | 1:1f2d9982fa8c | 426 | { |
hudakz | 1:1f2d9982fa8c | 427 | unistd::close(sd); |
hudakz | 1:1f2d9982fa8c | 428 | } |
hudakz | 1:1f2d9982fa8c | 429 | |
hudakz | 1:1f2d9982fa8c | 430 | /******************* |
hudakz | 1:1f2d9982fa8c | 431 | * Private methods * |
hudakz | 1:1f2d9982fa8c | 432 | *******************/ |
hudakz | 1:1f2d9982fa8c | 433 | |
hudakz | 1:1f2d9982fa8c | 434 | //Returns a timespec struct with the time elapsed between start and end timespecs |
hudakz | 1:1f2d9982fa8c | 435 | timespec Serial::timeDiff(timespec start, timespec end) |
hudakz | 1:1f2d9982fa8c | 436 | { |
hudakz | 1:1f2d9982fa8c | 437 | timespec temp; |
hudakz | 1:1f2d9982fa8c | 438 | if ((end.tv_nsec - start.tv_nsec) < 0) { |
hudakz | 1:1f2d9982fa8c | 439 | temp.tv_sec = end.tv_sec - start.tv_sec - 1; |
hudakz | 1:1f2d9982fa8c | 440 | temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; |
hudakz | 1:1f2d9982fa8c | 441 | } |
hudakz | 1:1f2d9982fa8c | 442 | else { |
hudakz | 1:1f2d9982fa8c | 443 | temp.tv_sec = end.tv_sec - start.tv_sec; |
hudakz | 1:1f2d9982fa8c | 444 | temp.tv_nsec = end.tv_nsec - start.tv_nsec; |
hudakz | 1:1f2d9982fa8c | 445 | } |
hudakz | 1:1f2d9982fa8c | 446 | |
hudakz | 1:1f2d9982fa8c | 447 | return temp; |
hudakz | 1:1f2d9982fa8c | 448 | } |
hudakz | 1:1f2d9982fa8c | 449 |