Subversion Repositories Projects

Rev

Rev 2099 | Rev 2598 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2099 Rev 2225
1
/****************************************************************************
1
/****************************************************************************
2
 *   Copyright (C) 2009-2015 by Claas Anders "CaScAdE" Rathje               *
2
 *   Copyright (C) 2009-2016 by Claas Anders "CaScAdE" Rathje               *
3
 *   admiralcascade@gmail.com                                               *
3
 *   admiralcascade@gmail.com                                               *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
5
 *                                                                          *
5
 *                                                                          *
6
 *   This program is free software; you can redistribute it and/or modify   *
6
 *   This program is free software; you can redistribute it and/or modify   *
7
 *   it under the terms of the GNU General Public License as published by   *
7
 *   it under the terms of the GNU General Public License as published by   *
8
 *   the Free Software Foundation; either version 2 of the License.         *
8
 *   the Free Software Foundation; either version 2 of the License.         *
9
 *                                                                          *
9
 *                                                                          *
10
 *   This program is distributed in the hope that it will be useful,        *
10
 *   This program is distributed in the hope that it will be useful,        *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13
 *   GNU General Public License for more details.                           *
13
 *   GNU General Public License for more details.                           *
14
 *                                                                          *
14
 *                                                                          *
15
 *   You should have received a copy of the GNU General Public License      *
15
 *   You should have received a copy of the GNU General Public License      *
16
 *   along with this program; if not, write to the                          *
16
 *   along with this program; if not, write to the                          *
17
 *   Free Software Foundation, Inc.,                                        *
17
 *   Free Software Foundation, Inc.,                                        *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
19
 ****************************************************************************/
19
 ****************************************************************************/
20
 
20
 
21
#include "main.h"
21
#include "main.h"
22
#include <avr/io.h>
22
#include <avr/io.h>
23
#include <avr/interrupt.h>
23
#include <avr/interrupt.h>
24
#include "spi.h"
24
#include "spi.h"
25
 
25
 
26
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
26
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
27
 
27
 
28
volatile uint16_t icnt = 0;
28
volatile uint16_t icnt = 0;
29
volatile uint8_t request_count = 0;
29
volatile uint8_t request_count = 0;
30
volatile uint8_t spi_ready = 1;
30
volatile uint8_t spi_ready = 1;
31
volatile union SPI_buffer_t SPI_buffer;
31
volatile union SPI_buffer_t SPI_buffer;
32
int16_t ampere = 0, max_ampere = 0, s_volt;
32
int16_t ampere = 0, max_ampere = 0, s_volt;
33
int32_t ampere_wasted = 0;
33
int32_t ampere_wasted = 0;
34
 
34
 
35
#define INT0_HIGH                       PORTD |=  (1 << PD2);
35
#define INT0_HIGH                       PORTD |=  (1 << PD2);
36
#define INT0_LOW                        PORTD &= ~(1 << PD2);
36
#define INT0_LOW                        PORTD &= ~(1 << PD2);
37
 
37
 
38
/**
38
/**
39
 * init the SPI as master
39
 * init the SPI as master
40
 */
40
 */
41
void SpiMasterInit(void) {
41
void SpiMasterInit(void) {
42
    volatile char IOReg;
42
    volatile char IOReg;
43
    // set PB4(/SS), PB5(MOSI), PB7(SCK) as output
43
    // set PB4(/SS), PB5(MOSI), PB7(SCK) as output
44
    DDRB = (1 << PB4) | (1 << PB5) | (1 << PB7);
44
    DDRB = (1 << PB4) | (1 << PB5) | (1 << PB7);
45
    PORTB |= (1 << PB4); // pullup SS
45
    PORTB |= (1 << PB4); // pullup SS
46
    // enable SPI Interrupt and SPI in Master Mode with SCK = CK/128
46
    // enable SPI Interrupt and SPI in Master Mode with SCK = CK/128
47
    SPCR = (1 << SPIE) | (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1);
47
    SPCR = (1 << SPIE) | (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1);
48
    IOReg = SPSR; // clear SPIF bit in SPSR
48
    IOReg = SPSR; // clear SPIF bit in SPSR
49
    IOReg = SPDR;
49
    IOReg = SPDR;
50
    //sei(); // we do it later
50
    //sei(); // we do it later
51
}
51
}
52
 
52
 
53
/**
53
/**
54
 * SPI interrupt handler
54
 * SPI interrupt handler
55
 */
55
 */
56
ISR(SPI_STC_vect) {
56
ISR(SPI_STC_vect) {
57
    if (request_count == 0) {
57
    if (request_count == 0) {
58
        SPI_buffer.buffer.chk = SPDR; // firs char received is check byte from last transfer
58
        SPI_buffer.buffer.chk = SPDR; // firs char received is check byte from last transfer
59
    } else {
59
    } else {
60
        SPI_buffer.buffer.c[request_count - 1] = SPDR; // safe received byte to buffer
60
        SPI_buffer.buffer.c[request_count - 1] = SPDR; // safe received byte to buffer
61
    }
61
    }
62
    request_count++;
62
    request_count++;
63
    if (--icnt) {
63
    if (--icnt) {
64
        //SPDR = *iptr; // send next byte
64
        //SPDR = *iptr; // send next byte
65
        spi_ready = 1; // we _should_ send later because the slave needs more time
65
        spi_ready = 1; // we _should_ send later because the slave needs more time
66
    } else {
66
    } else {
67
        SPCR &= ~_BV(SPIE); // deactivate interrupt
67
        SPCR &= ~_BV(SPIE); // deactivate interrupt
68
        INT0_HIGH // transfer is done, slave does not need to listen
68
        INT0_HIGH // transfer is done, slave does not need to listen
69
    }
69
    }
70
}
70
}
71
 
71
 
72
/**
72
/**
73
 * check if SPI transfer is still busy
73
 * check if SPI transfer is still busy
74
 */
74
 */
75
int TransferIsBusy(void) {
75
int TransferIsBusy(void) {
76
    return SPCR & _BV(SPIE);
76
    return SPCR & _BV(SPIE);
77
}
77
}
78
 
78
 
79
/**
79
/**
80
 * start a new transfer with length <len>
80
 * start a new transfer with length <len>
81
 */
81
 */
82
void StartTransfer(uint16_t len) {
82
void StartTransfer(uint16_t len) {
83
    INT0_LOW // /SS LOW ^= SS HIGH ^= slave should listen
83
    INT0_LOW // /SS LOW ^= SS HIGH ^= slave should listen
84
 
84
 
85
    // this is a new request
85
    // this is a new request
86
    request_count = 0;
86
    request_count = 0;
87
 
87
 
88
    // set up pointer and length for interrupt handler
88
    // set up pointer and length for interrupt handler
89
    icnt = len;
89
    icnt = len;
90
 
90
 
91
    SPCR |= _BV(SPIE); // enable spi interrupt
91
    SPCR |= _BV(SPIE); // enable spi interrupt
92
    SPDR = 'A'; // start transfer by first command char
92
    SPDR = 'A'; // start transfer by first command char
93
}
93
}
94
 
94
 
95
/**
95
/**
96
 * send next command through spi
96
 * send next command through spi
97
 */
97
 */
98
void spi_send_next() {
98
void spi_send_next() {
99
    SPDR = 'A' + request_count;
99
    SPDR = 'A' + request_count;
100
}
100
}
101
 
101
 
102
#endif
102
#endif
103
 
103