Subversion Repositories Projects

Rev

Rev 728 | Rev 902 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/****************************************************************************
 *   Copyright (C) 2009-2010 by Claas Anders "CaScAdE" Rathje               *
 *   admiralcascade@gmail.com                                               *
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
 *                                                                          *
 *   This program is free software; you can redistribute it and/or modify   *
 *   it under the terms of the GNU General Public License as published by   *
 *   the Free Software Foundation; either version 2 of the License.         *
 *                                                                          *
 *   This program is distributed in the hope that it will be useful,        *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *   GNU General Public License for more details.                           *
 *                                                                          *
 *   You should have received a copy of the GNU General Public License      *
 *   along with this program; if not, write to the                          *
 *   Free Software Foundation, Inc.,                                        *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
 ****************************************************************************/


#include <avr/io.h>
#include <avr/interrupt.h>
#include "spi.h"
#include "main.h"

#if !(ALLCHARSDEBUG|(WRITECHARS != -1))

volatile uint16_t icnt = 0;
volatile uint8_t request_count = 0;
volatile uint8_t spi_ready = 1;
volatile union SPI_buffer_t SPI_buffer;
int16_t ampere = 0, max_ampere = 0, s_volt;
int32_t ampere_wasted = 0;

#define INT0_HIGH                       PORTD |=  (1 << PD2);
#define INT0_LOW                        PORTD &= ~(1 << PD2);

/**
 * init the SPI as master
 */

void SpiMasterInit(void) {
    volatile char IOReg;
    // set PB4(/SS), PB5(MOSI), PB7(SCK) as output
    DDRB = (1 << PB4) | (1 << PB5) | (1 << PB7);
    PORTB |= (1 << PB4); // pullup SS
    // enable SPI Interrupt and SPI in Master Mode with SCK = CK/128
    SPCR = (1 << SPIE) | (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1);
    IOReg = SPSR; // clear SPIF bit in SPSR
    IOReg = SPDR;
    //sei(); // we do it later
}

/**
 * SPI interrupt handler
 */

ISR(SPI_STC_vect) {
    if (request_count == 0) {
        SPI_buffer.buffer.chk = SPDR; // firs char received is check byte from last transfer
    } else {
        SPI_buffer.buffer.c[request_count - 1] = SPDR; // safe received byte to buffer
    }
    request_count++;
    if (--icnt) {
        //SPDR = *iptr; // send next byte
        spi_ready = 1; // we _should_ send later because the slave needs more time
    } else {
        SPCR &= ~_BV(SPIE); // deactivate interrupt
        INT0_HIGH // transfer is done, slave does not need to listen
    }
}

/**
 * check if SPI transfer is still busy
 */

int TransferIsBusy(void) {
    return SPCR & _BV(SPIE);
}

/**
 * start a new transfer with length <len>
 */

void StartTransfer(uint16_t len) {
    INT0_LOW // /SS LOW ^= SS HIGH ^= slave should listen

    // this is a new request
    request_count = 0;

    // set up pointer and length for interrupt handler
    icnt = len;

    SPCR |= _BV(SPIE); // enable spi interrupt
    SPDR = 'A'; // start transfer by first command char
}

/**
 * send next command through spi
 */

void spi_send_next() {
    SPDR = 'A' + request_count;
}

#endif