/* * * 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 * * 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 . * */ #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; }