Zimin Wang / Mbed 2 deprecated DDRO_Farrari

Dependencies:   mbed-rtos mbed

Fork of DDRO_Farrari by Liangzhen Lai

basic_io.cpp

Committer:
josewang
Date:
2014-02-25
Revision:
10:95e9932f7990

File content as of revision 10:95e9932f7990:

/*
 * Implementation of a family of print and scan functions
 *
 * Written by Zimin Wang
 */
#include <stdarg.h>
#include <stdio.h>
#include "mbed.h"
#include "rtos.h"
#include "mmap.h"
#include "signal.h"
#include "pinout.h"
#include "basic_io.h"

#define TERMBUF_SIZE (256)

// mutex to serialize terminal read and write so that input/output won't be interleaved
static Mutex term_write_mutex;
static Mutex term_read_mutex;
// mutex to lock ram buffer
static Mutex rambuf_mutex;

// buffer for read from or write to terminal
static char term_txbuffer[TERMBUF_SIZE];
static char term_rxbuffer[TERMBUF_SIZE];

// Each time we can only read/write 4 bytes of data from/to ram buffer through JTAG
static union byte_chunk_union {
    unsigned int word;
    char bytes[4];
} byte_chunk;


// Actual function called when read from or write to terminal.
// Send buffer to stdout.
static void term_sendbuffer(const char *buffer, size_t size);
// Read stdin and write a maximum of size bytes data to buffer.
static void term_readbuffer(char *buffer, size_t size);


int mbed_printf(const char *format, ...) {
    int size;
    va_list args;
    
    va_start(args, format); 
    size = mbed_vprintf(format, args);
    va_end(args);
       
    return size; 
}

int mbed_vprintf(const char *format, va_list args) {
    int size;
    
    // tx_line is in critical section. We need a mutex to protect it.
    term_write_mutex.lock(); 
    size = vsnprintf(term_txbuffer, TERMBUF_SIZE, format, args);
    term_sendbuffer(term_txbuffer, TERMBUF_SIZE);
    term_write_mutex.unlock();
    
    return size;
}

// prompt user to input data from terminal
int mbed_scanf(const char *format, ...) {
    int size;
    va_list args;
    
    va_start(args, format);
    size = mbed_vscanf(format, args);
    va_end(args);
    
    return size;
}

int mbed_vscanf(const char *format, va_list args) {
    int size;
    
    // rx_line is in critical section, we need a mutex to protect it.
    term_read_mutex.lock();
    term_readbuffer(term_rxbuffer, TERMBUF_SIZE);
    size = vsscanf(term_rxbuffer, format, args);
    term_read_mutex.unlock();
    return size;   
}

int term_printf(JTAG *pJtag) {
    // acquire locks
    rambuf_mutex.lock();
    term_write_mutex.lock();
    // read data from ram buffer
    char *cp = term_txbuffer;
    bool finished = false;
    int len = 0;
    for (unsigned int i = RAMBUF_BEGIN; i < RAMBUF_END; i += 4) {
        byte_chunk.word = pJtag->readMemory(i);
        for (int j = 0; j < 4; ++j) {
            if (byte_chunk.bytes[j] != '\0') {
                *cp++ = byte_chunk.bytes[j];
                ++len;
            }
            else {
                finished = true;
                break;
            }
        }
        if (finished)
            break;
    }
    *cp = '\0';
    
    term_sendbuffer(term_txbuffer, TERMBUF_SIZE);
    // release locks
    term_write_mutex.unlock();
    rambuf_mutex.unlock();
    return len;
}

int term_scanf(JTAG *pJtag) {
    // acquire locks
    rambuf_mutex.lock();
    term_read_mutex.lock();
    // read from terminal and write to ram buffer
    term_readbuffer(term_rxbuffer, RAMBUF_SIZE);
    char *cp = term_rxbuffer;
    bool finished = false;
    int len = 0;
    for (int i = RAMBUF_BEGIN; i < RAMBUF_END; i+= 4) {
        for (int j = 0; j < 4; ++j) {
            if (*cp) {
                byte_chunk.bytes[j] = *cp++;
                ++len;
            } else {
                byte_chunk.bytes[j] = '\0';
                finished = true;
            }
        }
        pJtag->writeMemory(i, byte_chunk.word);
        if (finished)
            break;
    }
    // release locks
    term_read_mutex.unlock();
    rambuf_mutex.unlock();
    return len;
}

void debug_print(JTAG *pJtag) {
    // print the content of ram buffer
    unsigned int value;
    for (unsigned int i = RAMBUF_BEGIN; i < RAMBUF_END; i+=4) {
        value = pJtag->readMemory(i);
        mbed_printf("%08x\r\n", value);
    }
    value = pJtag->readMemory(IO_TYPE);
    mbed_printf("%8x\r\n", value);
}

static void term_sendbuffer(const char *buffer, size_t size) {
    int i;
    
    i = 0;
    while (i < size) {
        if (buffer[i] != '\0' && pc.writeable()) {
            pc.putc(buffer[i++]);
        } else if (buffer[i] == '\0') {
            break;
        }
    }
    return;
}

static void term_readbuffer(char *buffer, size_t size) {
    int i;
    char temp;

    i = 0;
    while (i < size-1) { // save for null character
        if (pc.readable()) {
            temp = pc.getc();
            if (temp == '\r')
                break;
            else
                buffer[i++] = temp;
        }
    }
    buffer[i] = '\0';
    return;
}