summaryrefslogtreecommitdiff
path: root/software/hhd70dongle/c1101lib.c
blob: 26d5fb96c75a86c0c5fb80e0238ae576f0f3d1c1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 *
 *  mur.sat
 *
 *  Somewhen in the year 2012, mur.at will have a nano satellite launched
 *  into a low earth orbit (310 km above the surface of our planet). The
 *  satellite itself is a TubeSat personal satellite kit, developed and
 *  launched by interorbital systems. mur.sat is a joint venture of mur.at,
 *  ESC im Labor and realraum.
 *
 *  Please visit the project hompage at sat.mur.at for further information.
 *
 *
 *  Copyright (C) 2012 Bernhard Tittelbach <xro@realraum.at>
 *
 *  This file is part of mur.sat.
 *
 *  mur.sat 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 3 of the License, or
 *  any later version.
 *
 *  mur.sat 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 mur.sat. If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include "avr/io.h"
#include "util/delay.h"

#include "c1101lib.h"
#include "spi.h"
//#include "usb_rawhid.h"

/**** Helper Functions ****/

char spi_c1101_exchange(char *data, int len)
{
    char rbyte;
    spi_cs_enable();
    while (len--)
    {
        while ( ! (SPIC1101_SB_CHIPRDY(spi_read_byte())));
        spi_write_byte(*(data++));
    }
    rbyte = spi_read_byte();
    spi_cs_disable();
    return rbyte;
}

// note addresses range from 0x00 to 0x2F for normal registers and 0xF0 to 0xFD for special status registers
char spi_c1101_read_register(char address)
{
    char data[1];
    data[0]=address | 0x80;
    return spi_c1101_exchange(data, 1);
}

// note addresses range from 0x00 to 0x2F for normal registers
char spi_c1101_write_register(char address, char byte)
{
    char data[2];
    data[0]=address & 0x2F;
    data[1]=byte;
    return spi_c1101_exchange(data, 2);
}

// note addresses range from 0x30 to 0x3D for command strobes
char spi_c1101_strobe_command(char address)
{
    char data[1];
    data[0]=address;
    return spi_c1101_exchange(data, 1);
}

int spi_c1101_read_rxfifo(int leave_num_bytes, char *buffer, int maxlen)
{
    char sb;
    int num_read = 0;
    int num_fifo_available = 0;
    spi_cs_enable();
    while ( ! (SPIC1101_SB_CHIPRDY(spi_read_byte())));
    spi_write_byte(SPIC1101_ADDR_FIFO_READ_BURST);
    do
    {
        sb = spi_read_byte();
    } while ( ! (SPIC1101_SB_CHIPRDY(sb)));
    num_fifo_available = SPIC1101_SB_FIFO_BYTES_AVAILABLE(sb);
    
    while (maxlen-- && num_fifo_available - num_read <= leave_num_bytes)
    {
        //hope this works !!
        buffer[num_read++] = spi_read_byte();
    }
    spi_cs_disable();
    return num_read;
}

//note: always check if num_written returned == len given
int spi_c1101_write_txfifo(char *buffer, int len)
{
    char sb;
    int num_written = 0;
    int num_fifo_available = 0;
    spi_cs_enable();
    while ( ! (SPIC1101_SB_CHIPRDY(spi_read_byte())));
    spi_write_byte(SPIC1101_ADDR_FIFO_WRITE_BURST);
    do
    {
        sb = spi_read_byte();
    } while ( ! (SPIC1101_SB_CHIPRDY(sb)));
    num_fifo_available = SPIC1101_SB_FIFO_BYTES_AVAILABLE(sb);
    
    //if there is less space in tx-fifo than num-byte we want to send, only fill fifo until full and leave rest of buffer unsent (for now)
    if (num_fifo_available < len)
        len = num_fifo_available;
    
    while (len--)
    {
        //hope this works !!
        spi_write_byte(buffer[num_written++]);
    }
    spi_cs_disable();
    return num_written;
}



/**** External Functions ****/


//max len: 64 bytes
void writeTXFifo(char *buffer, unsigned int len)
{
    //check TXBYTES.NUM_TXBYTES
    // never write more bytes than avaiblabe or doom ensues
    
    
}

//max returned: 64 bytes
int readRXFifo(char *buffer)
{
    //check RXBYTES.NUM_RXBYTES
    // never read more bytes than avaiblabe or we will read garbage
    
    //note: if RX transmission fills fifo buffer at exact same time as last RX Fifo Bit is read via SPI, Fifo Pointer will not be properly updated 
    //            and last read byte will be duplicated.
    // thus: don't last avialable FIFO Bytes unless we can be sure that it will be the last byte of a packet and we can be sure that a following duplicated byte is actually an Fifo duplication and not an actually recieved byte !
    
    return 0;
}