📄 spi.c
字号:
/* -*- c++ -*- *//* * Copyright 2004,2006 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio 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, or (at your option) * any later version. * * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */#include "spi.h"#include "usrp_rev2_regs.h"static voidsetup_enables (unsigned char enables){ // Software eanbles are active high. // Hardware enables are active low. // Uhh, the CODECs are active low, but the FPGA is active high... enables ^= SPI_ENABLE_FPGA; // KLUDGE: This code is fragile, but reasonably fast... // low three bits of enables go into port A USRP_PA = USRP_PA | (0x7 << 3); // disable FPGA, CODEC_A, CODEC_B USRP_PA ^= (enables & 0x7) << 3; // enable specified devs // high four bits of enables go into port E USRP_PE = USRP_PE | (0xf << 4); // disable TX_A, RX_A, TX_B, RX_B USRP_PE ^= (enables & 0xf0); // enable specified devs}#define disable_all() setup_enables (0)voidinit_spi (void){ disable_all (); /* disable all devs */ bitS_OUT = 0; /* idle state has CLK = 0 */}#if 0static unsigned charcount_bits8 (unsigned char v){ static unsigned char count4[16] = { 0, // 0 1, // 1 1, // 2 2, // 3 1, // 4 2, // 5 2, // 6 3, // 7 1, // 8 2, // 9 2, // a 3, // b 2, // c 3, // d 3, // e 4 // f }; return count4[v & 0xf] + count4[(v >> 4) & 0xf];}#elsestatic unsigned charcount_bits8 (unsigned char v){ unsigned char count = 0; if (v & (1 << 0)) count++; if (v & (1 << 1)) count++; if (v & (1 << 2)) count++; if (v & (1 << 3)) count++; if (v & (1 << 4)) count++; if (v & (1 << 5)) count++; if (v & (1 << 6)) count++; if (v & (1 << 7)) count++; return count;}#endifstatic voidwrite_byte_msb (unsigned char v);static voidwrite_bytes_msb (const xdata unsigned char *buf, unsigned char len);static voidread_bytes_msb (xdata unsigned char *buf, unsigned char len); // returns non-zero if successful, else 0unsigned charspi_read (unsigned char header_hi, unsigned char header_lo, unsigned char enables, unsigned char format, xdata unsigned char *buf, unsigned char len){ if (count_bits8 (enables) > 1) return 0; // error, too many enables set setup_enables (enables); if (format & SPI_FMT_LSB){ // order: LSB#if 1 return 0; // error, not implemented#else switch (format & SPI_FMR_HDR_MASK){ case SPI_FMT_HDR_0: break; case SPI_FMT_HDR_1: write_byte_lsb (header_lo); break; case SPI_FMT_HDR_2: write_byte_lsb (header_lo); write_byte_lsb (header_hi); break; default: return 0; // error } if (len != 0) read_bytes_lsb (buf, len);#endif } else { // order: MSB switch (format & SPI_FMT_HDR_MASK){ case SPI_FMT_HDR_0: break; case SPI_FMT_HDR_1: write_byte_msb (header_lo); break; case SPI_FMT_HDR_2: write_byte_msb (header_hi); write_byte_msb (header_lo); break; default: return 0; // error } if (len != 0) read_bytes_msb (buf, len); } disable_all (); return 1; // success}// returns non-zero if successful, else 0unsigned charspi_write (unsigned char header_hi, unsigned char header_lo, unsigned char enables, unsigned char format, const xdata unsigned char *buf, unsigned char len){ setup_enables (enables); if (format & SPI_FMT_LSB){ // order: LSB#if 1 return 0; // error, not implemented#else switch (format & SPI_FMR_HDR_MASK){ case SPI_FMT_HDR_0: break; case SPI_FMT_HDR_1: write_byte_lsb (header_lo); break; case SPI_FMT_HDR_2: write_byte_lsb (header_lo); write_byte_lsb (header_hi); break; default: return 0; // error } if (len != 0) write_bytes_lsb (buf, len);#endif } else { // order: MSB switch (format & SPI_FMT_HDR_MASK){ case SPI_FMT_HDR_0: break; case SPI_FMT_HDR_1: write_byte_msb (header_lo); break; case SPI_FMT_HDR_2: write_byte_msb (header_hi); write_byte_msb (header_lo); break; default: return 0; // error } if (len != 0) write_bytes_msb (buf, len); } disable_all (); return 1; // success}// ----------------------------------------------------------------static voidwrite_byte_msb (unsigned char v){ v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0; v = (v << 1) | (v >> 7); // rotate left (MSB into bottom bit) bitS_OUT = v & 0x1; bitS_CLK = 1; bitS_CLK = 0;}static voidwrite_bytes_msb (const xdata unsigned char *buf, unsigned char len){ while (len-- != 0){ write_byte_msb (*buf++); }}#if 0/* * This is incorrectly compiled by SDCC 2.4.0 */static unsigned charread_byte_msb (void){ unsigned char v = 0; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; v = v << 1; bitS_CLK = 1; v |= bitS_IN; bitS_CLK = 0; return v;}#elsestatic unsigned charread_byte_msb (void) _naked{ _asm clr a setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK setb _bitS_CLK mov c, _bitS_IN rlc a clr _bitS_CLK mov dpl,a ret _endasm;}#endifstatic voidread_bytes_msb (xdata unsigned char *buf, unsigned char len){ while (len-- != 0){ *buf++ = read_byte_msb (); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -