OpenCores
URL https://opencores.org/ocsvn/gecko3/gecko3/trunk

Subversion Repositories gecko3

[/] [gecko3/] [trunk/] [GECKO3COM/] [gecko3com-fw/] [firmware/] [src/] [spi.c] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 nussgipfel
/* -*- c++ -*- */
2
/*
3
 * Copyright 2004,2006 Free Software Foundation, Inc.
4
 *
5
 * This file is part of GNU Radio
6
 *
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 *
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with GNU Radio; see the file COPYING.  If not, write to
19
 * the Free Software Foundation, Inc., 51 Franklin Street,
20
 * Boston, MA 02110-1301, USA.
21
 */
22
/************************************************************/
23
/** \file    spi.c
24
 *************************************************************
25
 *  \brief   SPI bus functions
26
 *
27
 *  \details Library to communicate with SPI devices
28
 *
29
 *  \author  GNU Radio guys
30
 */
31
 
32
#include "spi.h"
33
#include "debugprint.h"
34
 
35
#if 0
36
/*
37
static unsigned char
38
count_bits8 (unsigned char v)
39
{
40
  static unsigned char count4[16] = {
41
    0,  // 0
42
    1,  // 1
43
    1,  // 2
44
    2,  // 3
45
    1,  // 4
46
    2,  // 5
47
    2,  // 6
48
    3,  // 7
49
    1,  // 8
50
    2,  // 9
51
    2,  // a
52
    3,  // b
53
    2,  // c
54
    3,  // d
55
    3,  // e
56
    4   // f
57
  };
58
  return count4[v & 0xf] + count4[(v >> 4) & 0xf];
59
}
60
*/
61
#else
62
 
63
 /** \brief internal helper function to count the number of active (1) bits in a byte */
64
static unsigned char
65
count_bits8 (unsigned char v)
66
{
67
  unsigned char count = 0;
68
  if (v & (1 << 0)) count++;
69
  if (v & (1 << 1)) count++;
70
  if (v & (1 << 2)) count++;
71
  if (v & (1 << 3)) count++;
72
  if (v & (1 << 4)) count++;
73
  if (v & (1 << 5)) count++;
74
  if (v & (1 << 6)) count++;
75
  if (v & (1 << 7)) count++;
76
  return count;
77
}
78
#endif
79
 
80
 
81
static void
82
setup_enables (unsigned char enables)
83
{
84
  // Software eanbles are active high.
85
  // Hardware enables are active low.
86
 
87
  if(count_bits8(enables) > 1) {
88
    print_info("too many enables acitve\n");
89
    return;
90
  }
91
  else {
92
    enables &= bmSPI_CS_MASK;
93
    SPI_CS_PORT |= bmSPI_CS_MASK;   //disable all chipselect signals
94
    SPI_CS_PORT &= ~enables;
95
  }
96
}
97
 
98
#define disable_all()   setup_enables (0)
99
 
100
void
101
init_spi (void)
102
{
103
  disable_all ();               /* disable all devs       */
104
  bitSPI_MOSI = 0;               /* idle state has CLK = 0 */
105
}
106
static void
107
write_byte_msb (unsigned char v);
108
 
109
static void
110
write_bytes_msb (const xdata unsigned char *buf, unsigned char len);
111
 
112
static void
113
read_bytes_msb (xdata unsigned char *buf, unsigned char len);
114
 
115
 
116
// returns non-zero if successful, else 0
117
unsigned char
118
spi_read (unsigned char header_hi, unsigned char header_lo,
119
          unsigned char enables, unsigned char format,
120
          xdata unsigned char *buf, unsigned char len)
121
{
122
  if (count_bits8 (enables) > 1)
123
    return 0;            // error, too many enables set
124
 
125
  setup_enables (enables);
126
  /*
127
  if (format & bmSPI_FMT_LSB){          // order: LSB
128
#if 1
129
    return 0;           // error, not implemented
130
#else
131
    switch (format & bmSPI_HEADER){
132
    case SPI_HEADER_0:
133
      break;
134
    case bmSPI_HEADER_1:
135
      write_byte_lsb (header_lo);
136
      break;
137
    case bmSPI_HEADER_2:
138
      write_byte_lsb (header_lo);
139
      write_byte_lsb (header_hi);
140
      break;
141
    default:
142
      return 0;         // error
143
    }
144
    if (len != 0)
145
      read_bytes_lsb (buf, len);
146
#endif
147
  }
148
 
149
  else {                // order: MSB
150
  */
151
    switch (format & bmSPI_HEADER){
152
    case bmSPI_HEADER_0:
153
      break;
154
    case bmSPI_HEADER_1:
155
      write_byte_msb (header_lo);
156
      break;
157
    case bmSPI_HEADER_2:
158
      write_byte_msb (header_hi);
159
      write_byte_msb (header_lo);
160
      break;
161
    default:
162
      return 0;          // error
163
    }
164
    if (len != 0)
165
      read_bytes_msb (buf, len);
166
    //}
167
 
168
  disable_all ();
169
  return 1;             // success
170
}
171
 
172
 
173
// returns non-zero if successful, else 0
174
unsigned char
175
spi_write (unsigned char header_hi, unsigned char header_lo,
176
           unsigned char enables, unsigned char format,
177
           const xdata unsigned char *buf, unsigned char len)
178
{
179
  setup_enables (enables);
180
 
181
  /*  if (format & bmSPI_FORMAT_LSB){           // order: LSB
182
#if 1
183
    return 0;           // error, not implemented
184
#else
185
    switch (format & bmSPI_HEADER){
186
    case bmSPI_HEADER_0:
187
      break;
188
    case bmSPI_HEADER_1:
189
      write_byte_lsb (header_lo);
190
      break;
191
    case bmSPI_HEADER_2:
192
      write_byte_lsb (header_lo);
193
      write_byte_lsb (header_hi);
194
      break;
195
    default:
196
      return 0;         // error
197
    }
198
    if (len != 0)
199
      write_bytes_lsb (buf, len);
200
#endif
201
  }
202
 
203
  else {                // order: MSB
204
  */
205
    switch (format & bmSPI_HEADER){
206
    case bmSPI_HEADER_0:
207
      break;
208
    case bmSPI_HEADER_1:
209
      write_byte_msb (header_lo);
210
      break;
211
    case bmSPI_HEADER_2:
212
      write_byte_msb (header_hi);
213
      write_byte_msb (header_lo);
214
      break;
215
    default:
216
      return 0;          // error
217
    }
218
    if (len != 0)
219
      write_bytes_msb (buf, len);
220
    //}
221
 
222
  disable_all ();
223
  return 1;             // success
224
}
225
 
226
// ----------------------------------------------------------------
227
 
228
static void
229
write_byte_msb (unsigned char v)
230
{
231
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
232
  bitSPI_MOSI = v & 0x1;
233
  bitSPI_CLK = 1;
234
  bitSPI_CLK = 0;
235
 
236
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
237
  bitSPI_MOSI = v & 0x1;
238
  bitSPI_CLK = 1;
239
  bitSPI_CLK = 0;
240
 
241
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
242
  bitSPI_MOSI = v & 0x1;
243
  bitSPI_CLK = 1;
244
  bitSPI_CLK = 0;
245
 
246
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
247
  bitSPI_MOSI = v & 0x1;
248
  bitSPI_CLK = 1;
249
  bitSPI_CLK = 0;
250
 
251
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
252
  bitSPI_MOSI = v & 0x1;
253
  bitSPI_CLK = 1;
254
  bitSPI_CLK = 0;
255
 
256
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
257
  bitSPI_MOSI = v & 0x1;
258
  bitSPI_CLK = 1;
259
  bitSPI_CLK = 0;
260
 
261
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
262
  bitSPI_MOSI = v & 0x1;
263
  bitSPI_CLK = 1;
264
  bitSPI_CLK = 0;
265
 
266
  v = (v << 1) | (v >> 7);      // rotate left (MSB into bottom bit)
267
  bitSPI_MOSI = v & 0x1;
268
  bitSPI_CLK = 1;
269
  bitSPI_CLK = 0;
270
}
271
 
272
static void
273
write_bytes_msb (const xdata unsigned char *buf, unsigned char len)
274
{
275
  while (len-- != 0){
276
    write_byte_msb (*buf++);
277
  }
278
}
279
 
280
#if 0
281
/*
282
 * This is incorrectly compiled by SDCC 2.4.0
283
 */
284
/*static unsigned char
285
read_byte_msb (void)
286
{
287
  unsigned char v = 0;
288
 
289
  bitSPI_CLK = 1;
290
  v |= bitSPI_MISO;
291
  bitSPI_CLK = 0;
292
 
293
  v = v << 1;
294
  bitSPI_CLK = 1;
295
  v |= bitSPI_MISO;
296
  bitSPI_CLK = 0;
297
 
298
  v = v << 1;
299
  bitSPI_CLK = 1;
300
  v |= bitSPI_MISO;
301
  bitSPI_CLK = 0;
302
 
303
  v = v << 1;
304
  bitSPI_CLK = 1;
305
  v |= bitSPI_MISO;
306
  bitSPI_CLK = 0;
307
 
308
  v = v << 1;
309
  bitSPI_CLK = 1;
310
  v |= bitSPI_MISO;
311
  bitSPI_CLK = 0;
312
 
313
  v = v << 1;
314
  bitSPI_CLK = 1;
315
  v |= bitSPI_MISO;
316
  bitSPI_CLK = 0;
317
 
318
  v = v << 1;
319
  bitSPI_CLK = 1;
320
  v |= bitSPI_MISO;
321
  bitSPI_CLK = 0;
322
 
323
  v = v << 1;
324
  bitSPI_CLK = 1;
325
  v |= bitSPI_MISO;
326
  bitSPI_CLK = 0;
327
 
328
  return v;
329
  } */
330
#else
331
static unsigned char
332
read_byte_msb (void) _naked
333
{
334
  _asm
335
        clr     a
336
 
337
        setb    _bitSPI_CLK
338
        mov     c, _bitSPI_MISO
339
        rlc     a
340
        clr     _bitSPI_CLK
341
 
342
        setb    _bitSPI_CLK
343
        mov     c, _bitSPI_MISO
344
        rlc     a
345
        clr     _bitSPI_CLK
346
 
347
        setb    _bitSPI_CLK
348
        mov     c, _bitSPI_MISO
349
        rlc     a
350
        clr     _bitSPI_CLK
351
 
352
        setb    _bitSPI_CLK
353
        mov     c, _bitSPI_MISO
354
        rlc     a
355
        clr     _bitSPI_CLK
356
 
357
        setb    _bitSPI_CLK
358
        mov     c, _bitSPI_MISO
359
        rlc     a
360
        clr     _bitSPI_CLK
361
 
362
        setb    _bitSPI_CLK
363
        mov     c, _bitSPI_MISO
364
        rlc     a
365
        clr     _bitSPI_CLK
366
 
367
        setb    _bitSPI_CLK
368
        mov     c, _bitSPI_MISO
369
        rlc     a
370
        clr     _bitSPI_CLK
371
 
372
        setb    _bitSPI_CLK
373
        mov     c, _bitSPI_MISO
374
        rlc     a
375
        clr     _bitSPI_CLK
376
 
377
        mov     dpl,a
378
        ret
379
  _endasm;
380
}
381
#endif
382
 
383
static void
384
read_bytes_msb (xdata unsigned char *buf, unsigned char len)
385
{
386
  while (len-- != 0){
387
    *buf++ = read_byte_msb ();
388
  }
389
}
390
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.