For test

Dependencies:   mbed

ArduinoSerial.cpp

Committer:
shennongmin
Date:
2015-02-03
Revision:
11:7bd1b2a67b1a
Parent:
10:9d4ec0359a5c
Child:
12:4e4e72f18047

File content as of revision 11:7bd1b2a67b1a:

#include "ArduinoSerial.h"

LinkedListNode ArduinoSerial::list_head = {NULL, NULL};
unsigned int ArduinoSerial::instance_counter = 0;

void ArduinoSerial::uart_irq_callback(void) {
    LinkedListNode *p;
    for (p = list_head.next; p != &list_head; p = p->next) {
        if (p->data != NULL) {
            while(p->data->readable()) {
                p->data->write_char(p->data->getc());
            }
        }
    }
}

ArduinoSerial::ArduinoSerial(PinName tx, PinName rx):Serial(tx, rx) {
    printf("Constructor\r\n");
    instance_counter++;
    if (instance_counter == 1) {
        init_list_head_node(&list_head);
    }
    
    if (add_node_to_tail(&list_head, this) != NULL) {
        this->attach(&uart_irq_callback);    
        printf("Create instance 0x%X ok!\r\n", this);
    } else {
        printf("Create instance 0x%X failed!\r\n", this);
    }
}
    
ArduinoSerial::~ArduinoSerial(void) {
    instance_counter--;
    if (del_node_by_data(&list_head, this) != NULL) {
        this->attach(NULL); 
        printf("Release instance 0x%X ok!\r\n", this);
    } else {
        printf("Release instance 0x%X failed!\r\n", this);
    }
}
    
void ArduinoSerial::begin(int baud_rate) {
    baud(baud_rate);
    flush();
}
    
int ArduinoSerial::available(void) {
    return (unsigned int)(ARDUINOSERIAL_BUFFER_SIZE + rx_buffer.head - rx_buffer.tail) % ARDUINOSERIAL_BUFFER_SIZE;
}

/* 清空接收缓冲区的数据 */
void ArduinoSerial::flush(void)
{
    memset(&rx_buffer, 0, sizeof(rx_buffer));
}

char ArduinoSerial::read_char(void) {
    // if the head isn't ahead of the tail, we don't have any characters
    if (rx_buffer.head == rx_buffer.tail) {
        return (char)-1;
    } else {
        unsigned char c = rx_buffer.buffer[rx_buffer.tail];
        rx_buffer.tail = (unsigned int)(rx_buffer.tail + 1) % ARDUINOSERIAL_BUFFER_SIZE;
        return c;
    }
}

void ArduinoSerial::setTimeout(unsigned long millisecond) {
    find_timeout = millisecond;
}

/* 在超时之前, 如果在串口接收数据缓冲区中找到了定长字符串 str 就返回 true, 如果超时, 返回 false */
bool ArduinoSerial::find(const char *str) {
    bool ret = false;
    String data;
    char c;
    unsigned long i;
    printf("1.0\r\n");
    for (i = 0; i < find_timeout; i++) {
        while(available() > 0) {
            c = read_char();
            data += c;
        }
        if (data.indexOf(String(str)) != -1) {
            ret = true;
            break;
        }
        delay(1);
    }
    printf("1.9\r\n");
    return ret;
}

size_t ArduinoSerial::write(uint8_t data) {
    putc(data);
    return 1;
}

void ArduinoSerial::write_char(unsigned char c) {
    int i = (unsigned int)(rx_buffer.head + 1) % ARDUINOSERIAL_BUFFER_SIZE;

    // if we should be storing the received character into the location
    // just before the tail (meaning that the head would advance to the
    // current location of the tail), we're about to overflow the buffer
    // and so we don't write the character or advance the head.
    if (i != rx_buffer.tail) {
        rx_buffer.buffer[rx_buffer.head] = c;
        rx_buffer.head = i;
    }
}

LinkedListNode *ArduinoSerial::init_list_head_node(LinkedListNode *head) {
    if (head == NULL) {
        return NULL;
    }
    head->data = NULL;
    head->next = head;
    return head;
}

LinkedListNode *ArduinoSerial::add_node_to_tail(LinkedListNode *head, ArduinoSerial* data) {
    LinkedListNode *p;
    LinkedListNode *node = (LinkedListNode *)malloc(sizeof(LinkedListNode));
    if (node == NULL) {
        return NULL;
    }
    /* 设置该节点的值 */
    node->data = data;
    node->next = head;
    
    /* 在末尾插入该节点 */
    for(p = head; p->next != head; p = p->next);
    p->next = node;
    
    return head;
}
LinkedListNode *ArduinoSerial::del_node_by_data(LinkedListNode *head, ArduinoSerial* data) {
    LinkedListNode *p;
    LinkedListNode *prev;
    
    if (head == NULL) {
        return NULL;
    }
    
    prev = head, p = head->next; 
    while(p != head) {
        if (p->data == data) {
            prev->next = p->next;
            free(p);
            p = prev->next;
        } else {
            prev = p;
            p = p->next;    
        }
    }
    return head;
}
LinkedListNode *ArduinoSerial::find_node_by_data(LinkedListNode *head, ArduinoSerial* data) {
    LinkedListNode *p;
    if (head == NULL) {
        return NULL;
    }
    
    for (p = head->next; p != head; p = p->next) {
        if (p->data == data) {
            return p;
        }
    }
    return NULL;
}