afLib 1.3 which is supporting both SPI and UART

Dependencies:   vt100 mbed afLib_1_3

af_utils/mbedSPI.cpp

Committer:
Rhyme
Date:
2018-04-23
Revision:
0:87662653a3c6

File content as of revision 0:87662653a3c6:

#include "mbed.h"
#include "afSPI.h"
#include "mbedSPI.h"
#include "afErrors.h"
#include "msg_types.h"
#include "vt100.h"
extern vt100 *tty ;

#if defined (TARGET_KL25Z) || defined (TARGET_TEENSY3_1)
 #ifndef SPI0_C1
  #define SPI0_C1 (*(uint8_t *)0x40076000)
 #endif
#endif

mbedSPI::mbedSPI(PinName mosi, PinName miso, PinName sckl, PinName cs) :
    _spi(mosi, miso, sckl), _cs(cs, 1)
{
    _spi.format(8, 0) ;
    _spi.frequency(1000000) ; /* 1MHz */

#if defined (TARGET_KL25Z) || defined (TARGET_TEENSY3_1)
    #ifndef SPI0_C1
        #define SPI0_C1 (*(uint8_t *)0x40076000)
    #endif
//    SPI0_C1 |= 0x01 ; /* LSB First */
//    SPI0_C1 &= 0xFE ; /* MSB First */
#endif

}

void mbedSPI::begin(void)
{
}

void mbedSPI::beginSPI(void)
{
    _cs = 0 ;
    SPI0_C1 |= 0x01 ; /* LSB First */
    wait_us(8) ;
}

void mbedSPI::endSPI(void)
{
    _cs = 1 ;
    SPI0_C1 &= 0xFE ; /* MSB First */
    wait_us(1) ;
    // SPI.endTransaction() // in the original code
}

/**
 * on 17-Jan-2018 disable/enable irq added
 * before and after of each _spi.writes
 */
void mbedSPI::transfer(char *bytes, int len)
{
    int i ;
    for (i = 0 ; i < len ; i++ ) {
        __disable_irq() ; // Disable Interrupts
        bytes[i] = _spi.write(bytes[i]) ;
        __enable_irq() ; // Enable Interrupts
    }
}

void mbedSPI::checkForInterrupt(volatile int *interrupts_pending, bool idle)
{
    // Nothing required here.
}

int  mbedSPI::exchangeStatus(StatusCommand *tx, StatusCommand *rx)
{
    int         result = afSUCCESS ;
    uint16_t    len = tx->getSize() ;
    int         *bytes ;
    char        *rbytes ;
    int         index = 0 ;
    bytes = new int[len] ;
    rbytes = new char[len + 1] ;
    tx->getBytes(bytes) ;
    
    beginSPI() ;
    for (int i = 0 ; i < len ; i++ ) {
        rbytes[i] = bytes[i] ;
    }
    rbytes[len] = tx->getChecksum() ;
    transfer(rbytes, len + 1) ;
    
    uint8_t cmd = bytes[index++] ;
    if (cmd != SYNC_REQUEST && cmd != SYNC_ACK) {
        tty->printf("exchangeStatus bad cmd: %02X\n", cmd) ;
        result = afERROR_INVALID_COMMAND ;
    }
    
    rx->setBytesToSend(rbytes[index + 0] | (rbytes[index + 1] << 8)) ;
    rx->setBytesToRecv(rbytes[index + 2] | (rbytes[index + 3] << 8)) ;
    rx->setChecksum(rbytes[index | 4]);
    
    endSPI() ;

    delete [] bytes ;
    delete [] rbytes ;    
    return result ;
}

int  mbedSPI::writeStatus(StatusCommand *c)
{
    int         result = afSUCCESS ;
    uint16_t    len = c->getSize() ;
    int         *bytes ;
    char         *rbytes ;
    int         index = 0 ;
    bytes = new int[len] ;
    rbytes = new char[len+1] ;
    c->getBytes(bytes) ;
    
    beginSPI() ;
    
    for (int i = 0 ; i < len ; i++ ) {
        rbytes[i] = bytes[i] ;
    }
    rbytes[len] = c->getChecksum() ;
    transfer(rbytes, len + 1) ;
    
    uint8_t cmd = rbytes[index++] ;
    if (cmd != SYNC_REQUEST && cmd != SYNC_ACK) {
        tty->printf("writeStatus bad cmd: %02X\n", cmd) ;
        result = afERROR_INVALID_COMMAND ;
    }
    
    endSPI() ;
    
    delete [] rbytes ;
    delete [] bytes ;
    
    return result ;
}

void mbedSPI::sendBytes(char *bytes, int len)
{
    beginSPI() ;
    
    transfer(bytes, len) ;

    endSPI() ;
}

void mbedSPI::recvBytes(char *bytes, int len)
{
    beginSPI() ;
    
    transfer(bytes, len) ;

    endSPI() ;
}

void mbedSPI::sendBytesOffset(char *bytes, uint16_t *bytesToSend, uint16_t *offset)
{
    uint16_t len = 0;

    len = *bytesToSend > SPI_FRAME_LEN ? SPI_FRAME_LEN : *bytesToSend;

    char *buffer ;
    buffer = new char[len] ;
    memset(buffer, 0xff, sizeof(buffer));

    memcpy(buffer, &bytes[*offset], len);

    sendBytes(buffer, len);

    *offset += len;
    *bytesToSend -= len;
    
    delete [] buffer ;
}

#if 1
void mbedSPI::recvBytesOffset(char **bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset)
{
    uint16_t len = 0;

    len = *bytesToRecv > SPI_FRAME_LEN ? SPI_FRAME_LEN : *bytesToRecv;

    if (*offset == 0) {
        *bytesLen = *bytesToRecv;
        *bytes = new char[*bytesLen];
    }

    char *start = *bytes + *offset;

    recvBytes(start, len);

    *offset += len;
    *bytesToRecv -= len;
}
#endif

#if 0
void mbedSPI::recvBytesOffset(char *bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset)
{
    uint16_t len = 0;

    len = *bytesToRecv > SPI_FRAME_LEN ? SPI_FRAME_LEN : *bytesToRecv;

    if (*offset == 0) {
        *bytesLen = *bytesToRecv;
//        *bytes = new char[*bytesLen];
    }

    char *start = bytes + *offset;

    recvBytes(start, len);

    *offset += len;
    *bytesToRecv -= len;
}
#endif