00001 00002 00003 00004 /***************************************************** 00005 SPI.h Joe Pardue October 29, 2010 00006 00007 REVISION DETAILS IN SPI.H 00008 00009 00010 ******************************************************/ 00011 00012 // I HATE LICENSES LIKE THIS >>BUT<< I've been told that without 00013 // the license then the work is automatically copyrighted in my name 00014 // since my purpose is to educate (and learn), I want the code to be 00015 // used by whoever wants to use it to learn something. If you like it, 00016 // then visit my website www.smileymicros.com and buy something. 00017 00018 /* 00019 * BSD License 00020 * ----------- 00021 * 00022 * Copyright (c) 2008, Smiley Micros, All rights reserved. 00023 * 00024 * Redistribution and use in source and binary forms, with or without 00025 * modification, are permitted provided that the following conditions are met: 00026 * 00027 * - Redistributions of source code must retain the above copyright notice, 00028 * this list of conditions and the following disclaimer. 00029 * 00030 * - Redistributions in binary form must reproduce the above copyright notice, 00031 * this list of conditions and the following disclaimer in the documentation 00032 * and/or other materials provided with the distribution. 00033 * 00034 * - Neither the name of the Smiley Micros nor the names of its contributors 00035 * may be used to endorse or promote products derived from this software 00036 * without specific prior written permission. 00037 * 00038 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00039 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00040 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00041 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00042 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00043 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00044 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00045 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00046 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00047 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00048 * POSSIBILITY OF SUCH DAMAGE. 00049 */ 00050 00051 // And to further cover my butt, let me add that if you use this software 00052 // it will destroy whatever machine you use it on and kill anyone in a one 00053 // kilometer radius. So don't even consider using it for any reason whatsoever! 00054 00055 /***************************************************** 00056 SPI.h provides headers for a library of SPI 00057 functions for four types of SPI: 00058 00059 Software SPI 00060 Hardware SPI 00061 USI SPI 00062 USART SPI 00063 00064 ******************************************************/ 00065 00066 #ifndef SPI_H 00067 #define SPI_H 00068 00069 #include <avr/io.h> 00070 #include "..\device\device.h" // defines device 00071 00072 /************************************************************/ 00081 /************************************************************/ 00082 #define DOXYGEN 00083 00084 /***************************************************** 00085 ****************************************************** 00086 TODO: EXPLAIN USING MULTIPLE SPI OF VARYING TYPES 00087 ******************************************************* 00088 ******************************************************/ 00089 00090 00091 /* ********************************************************** */ 00092 00093 00094 /***************************************************** 00095 Define number of SPI 00096 ******************************************************/ 00097 #define SPI0 00098 //#define SPI1 00099 //#define SPIx // place holder 00100 00101 #if defined (SPI0) 00102 /***************************************************** 00103 ****************************************************** 00104 SPI0 00105 ******************************************************* 00106 ******************************************************/ 00107 00108 /***************************************************** 00109 Declare SPI0 function 00110 ******************************************************/ 00111 void spi0_init_master(void); 00112 uint8_t spi0_master_rw8(uint8_t to_slave); 00113 uint16_t spi0_master_rw16(uint16_t to_slave); 00114 00115 /***************************************************** 00116 Define SPI0 type 00117 ******************************************************/ 00118 //#define SPI0_SOFT 00119 #define SPI0_HARD 00120 00121 00122 #if defined (SPI0_SOFT) 00123 /***************************************************** 00124 Software SPI 00125 ******************************************************/ 00126 private void spi0_soft_init_master(void); 00127 uint8_t spi0_soft_master_rw8(uint8_t to_slave); 00128 uint16_t spi0_soft_master_rw16(uint16_t to_slave); 00129 00130 00131 /************************************************************/ 00165 /************************************************************/ 00166 // Define ports, pins, and data direction registers for set up 00167 #define MOSI_PORT PORTB 00168 #define MOSI_PORT_PIN PORTB3 00169 #define MOSI_DDR DDRB 00170 #define MOSI_PORT_PINS PINB 00171 00172 #define MISO_PORT PORTB 00173 #define MISO_PORT_PIN PORTB4 00174 #define MISO_DDR DDRB 00175 #define MISO_PORT_PINS PINB 00176 00177 #define SCLK_PORT PORTB 00178 #define SCLK_PORT_PIN PORTB5 00179 #define SCLK_DDR DDRB 00180 00181 #define SS_PORT PORTB 00182 #define SS_PORT_PIN PORTB2 00183 #define SS_DDR DDRB 00184 00185 00186 /************************************************************/ 00202 /************************************************************/ 00203 // Move bitwise operations to macros to 00204 // help keep folks heads from exploding 00205 #define spi_soft_clear_ss() SS_PORT &= ~(1<<SS_PORT_PIN) 00206 #define spi_soft_set_ss() SS_PORT |= (1<<SS_PORT_PIN) 00207 #define spi_soft_set_mosi_bit() MOSI_PORT |= (1<<MOSI_PORT_PIN) 00208 #define spi_soft_clear_mosi_bit() MOSI_PORT &= ~(1<<MOSI_PORT_PIN) 00209 #define is_bit_set(myVar, i) (!!(myVar & (1 << i))) 00210 00211 // Return the data pin state 00212 uint8_t spi_soft_get_miso_bit(void); 00213 00214 // Return the data pin state 00215 uint8_t spi_soft_get_miso_pin(void); 00216 00217 // Turn the clock line 0 to 1 00218 void spi_soft_toggle_sclk(void); 00219 00220 // Initialize the SPI I/O pins 00221 void spi_soft_setup_pins(void); 00222 00223 00224 #elif defined (SPI0_HARD) 00225 /***************************************************** 00226 Hardware SPI 00227 ******************************************************/ 00228 void spi0_hard_init_master(void); 00229 uint8_t spi0_hard_master_rw8(uint8_t to_slave); 00230 uint16_t spi0_hard_master_rw16(uint16_t to_slave); 00231 00232 /************************************************************/ 00239 /************************************************************/ 00240 #define spi_hard_clear_ss() (SS_HARDWARE_PORT &= ~(1<<SS_HARDWARE_PIN)) 00241 #define spi_hard_set_ss() (SS_HARDWARE_PORT |= (1<<SS_HARDWARE_PIN)) 00242 00243 /************************************************************/ 00270 /************************************************************/ 00271 #if defined (DOXYGEN) 00272 #define MOSI_HARDWARE_PIN PORTxx 00273 #define MOSI_HARDWARE_DDR DDBx 00274 #define MISO_HARDWARE_PIN PORTxx 00275 #define MISO_HARDWARE_DDR DDxx 00276 #define SCLK_HARDWARE_PIN PORTxx 00277 #define SCLK_HARDWARE_DDR DDxx 00278 #define SS_HARDWARE_PORT PORTB 00279 #define SS_HARDWARE_PIN PORTB4 00280 #define SS_HARDWARE_DDR DDB4 00281 00282 #else 00283 00284 #if defined (Butterfly) 00285 #define MOSI_HARDWARE_PIN PORTB2 00286 #define MOSI_HARDWARE_DDR DDB2 00287 #define MISO_HARDWARE_PIN PORTB3 00288 #define MISO_HARDWARE_DDR DDB3 00289 #define SCLK_HARDWARE_PIN PORTB1 00290 #define SCLK_HARDWARE_DDR DDB1 00291 #define SS_HARDWARE_PORT PORTB 00292 #define SS_HARDWARE_PIN PORTB4 00293 #define SS_HARDWARE_DDR DDB4 00294 00295 #elif defined (Arduino) | (ATmega328) 00296 #define MOSI_HARDWARE_PIN PORTB3 00297 #define MOSI_HARDWARE_DDR DDB3 00298 #define MISO_HARDWARE_PIN PORTB4 00299 #define MISO_HARDWARE_DDR DDB4 00300 #define SCLK_HARDWARE_PIN PORTB5 00301 #define SCLK_HARDWARE_DDR DDB5 00302 #define SS_HARDWARE_PORT PORTB 00303 #define SS_HARDWARE_PIN PORTB2 00304 #define SS_HARDWARE_DDR DDB2 00305 00306 #elif defined (BeAVR40) | (ATmega644) 00307 #define MOSI_HARDWARE_PIN PB5 00308 #define MOSI_HARDWARE_DDR DDB5 00309 #define MISO_HARDWARE_PIN PB4 00310 #define MISO_HARDWARE_DDR DDB4 00311 #define SCLK_HARDWARE_PIN PB7 00312 #define SCLK_HARDWARE_DDR DDB7 00313 #define SS_HARDWARE_PIN PB6 00314 #define SS_HARDWARE_DDR DDB6 00315 00316 #else 00317 #error "no SPI pins declared" 00318 #endif 00319 00320 #endif // select for Doxygen 00321 00322 #elif defined (SPI0_USI) 00323 /***************************************************** 00324 USI SPI 00325 ******************************************************/ 00326 00327 #elif defined (SPI0_USART) 00328 /***************************************************** 00329 USART SPI 00330 ******************************************************/ 00331 00332 //#else 00333 // #error "no SPI0 type declared" 00334 #endif 00335 00336 //#else 00337 // #error "no SPI0 number declared" 00338 #endif // SPI0 00339 00340 00341 00342 00343 #if defined (SPI1) 00344 /***************************************************** 00345 ****************************************************** 00346 SPI1 00347 ******************************************************* 00348 ******************************************************/ 00349 00350 /***************************************************** 00351 Define SPI1 type 00352 ******************************************************/ 00353 #define SPI1_SOFT 00354 //#define SPI1_HARD 00355 //#define SPI1_USI 00356 //#define SPI1_USART 00357 00358 /***************************************************** 00359 Declare SPI1 function 00360 ******************************************************/ 00361 void spi1_initmaster(void); 00362 //void spi1_initslave(void); 00363 void spi1_put(uint8_t); 00364 uint8_t spi1_get(void); 00365 //void spi1_wait(void); 00366 00367 //Now allow for SPI1 for each type 00368 00369 00370 #if defined (SPI1_SOFT) 00371 /***************************************************** 00372 Software SPI 00373 ******************************************************/ 00374 00375 // Define ports, pins, and data direction registers for set up 00376 #define MOSI_PORT PORTB 00377 #define MOSI_PORT_PIN PORTB2 00378 #define MOSI_DDR DDRB 00379 #define MOSI_PORT_PINS PINB 00380 00381 #define MISO_PORT PORTB 00382 #define MISO_PORT_PIN PORTB1 00383 #define MISO_DDR DDRB 00384 #define MISO_PORT_PINS PINB 00385 00386 #define SCLK_PORT PORTD 00387 #define SCLK_PORT_PIN PORTD7 00388 #define SCLK_DDR DDRD 00389 00390 #define SS_PORT PORTB 00391 #define SS_PORT_PIN PORTB0 00392 #define SS_DDR DDRB 00393 00394 00395 // Move bitwise operations to macros to 00396 // help keep folks heads from exploding 00397 #define spi_soft_clear_ss() SS_PORT &= ~(1<<SS_PORT_PIN) 00398 #define spi_soft_set_ss() SS_PORT |= (1<<SS_PORT_PIN) 00399 #define spi_soft_set_mosi_bit() MOSI_PORT |= (1<<MOSI_PORT_PIN) 00400 #define spi_soft_clear_mosi_bit() MOSI_PORT &= ~(1<<MOSI_PORT_PIN) 00401 00402 #define is_bit_set(myVar, i) (!!(myVar & (1 << i))) 00403 00404 // Return the data pin state 00405 uint8_t spi_soft_get_miso_bit(void); 00406 00407 // Return the data pin state 00408 uint8_t spi_soft_get_miso_pin(void); 00409 00410 // Turn the clock line 0 to 1 00411 void spi_soft_toggle_sclk(void); 00412 00413 // Initialize the SPI I/O pins 00414 void spi_soft_setup_pins(void); 00415 00416 00417 #elif defined (SPI1_HARD) 00418 /***************************************************** 00419 Hardware SPI 00420 ******************************************************/ 00421 00422 00423 #elif defined (SPI1_USI) 00424 /***************************************************** 00425 USI SPI 00426 ******************************************************/ 00427 00428 // You have to set your own slave select 00429 #define SS_PORT PORTD 00430 #define SS_PORT_PIN PORTD7 00431 #define SS_DDR DDRD 00432 00433 #elif defined (SPI0_USART) 00434 /***************************************************** 00435 USART SPI 00436 ******************************************************/ 00437 00438 //#else 00439 // #error "no SPI1 type declared" 00440 #endif 00441 00442 //#else 00443 // #error "no SPI1 number declared" 00444 #endif // SPI1 00445 00446 00447 00448 00449 00450 #if defined (SPIx) 00451 /***************************************************** 00452 ****************************************************** 00453 SPIx 00454 ******************************************************* 00455 ******************************************************/ 00456 00457 /***************************************************** 00458 Define SPIx type 00459 ******************************************************/ 00460 #define SPIx_SOFT 00461 //#define SPIx_HARD 00462 //#define SPIx_USI 00463 //#define SPIx_USART 00464 00465 /***************************************************** 00466 Declare SPIx function 00467 ******************************************************/ 00468 void spix_initmaster(void); 00469 //void spix_initslave(void); 00470 void spix_put(uint8_t); 00471 uint8_t spix_get(void); 00472 //void spix_wait(void); 00473 00474 //Now allow for SPIx for each type 00475 00476 00477 #if defined (SPIx_SOFT) 00478 /***************************************************** 00479 Software SPx 00480 ******************************************************/ 00481 00482 // Define ports, pins, and data direction registers for set up 00483 #define MOSI_PORT PORTB 00484 #define MOSI_PORT_PIN PORTB2 00485 #define MOSI_DDR DDRB 00486 #define MOSI_PORT_PINS PINB 00487 00488 #define MISO_PORT PORTB 00489 #define MISO_PORT_PIN PORTB1 00490 #define MISO_DDR DDRB 00491 #define MISO_PORT_PINS PINB 00492 00493 #define SCLK_PORT PORTD 00494 #define SCLK_PORT_PIN PORTD7 00495 #define SCLK_DDR DDRD 00496 00497 #define SS_PORT PORTB 00498 #define SS_PORT_PIN PORTB0 00499 #define SS_DDR DDRB 00500 00501 00502 // Move bitwise operations to macros to 00503 // help keep folks heads from exploding 00504 #define spi_soft_clear_ss() SS_PORT &= ~(1<<SS_PORT_PIN) 00505 #define spi_soft_set_ss() SS_PORT |= (1<<SS_PORT_PIN) 00506 #define spi_soft_set_mosi_bit() MOSI_PORT |= (1<<MOSI_PORT_PIN) 00507 #define spi_soft_clear_mosi_bit() MOSI_PORT &= ~(1<<MOSI_PORT_PIN) 00508 00509 #define is_bit_set(myVar, i) (!!(myVar & (1 << i))) 00510 00511 // Return the data pin state 00512 uint8_t spi_soft_get_miso_bit(void); 00513 00514 // Return the data pin state 00515 uint8_t spi_soft_get_miso_pin(void); 00516 00517 // Turn the clock line 0 to 1 00518 void spi_soft_toggle_sclk(void); 00519 00520 // Initialize the SPI I/O pins 00521 void spi_soft_setup_pins(void); 00522 00523 00524 #elif defined (SPIx_HARD) 00525 /***************************************************** 00526 Hardware SPI 00527 ******************************************************/ 00528 00529 00530 #elif defined (SPIx_USI) 00531 /***************************************************** 00532 USI SPI 00533 ******************************************************/ 00534 00535 00536 #elif defined (SPIx_USART) 00537 /***************************************************** 00538 USART SPI 00539 ******************************************************/ 00540 00541 //#else 00542 // #error "no SPIx type declared" 00543 #endif 00544 //#else 00545 // #error "no SPIx number declared" 00546 #endif // SPIx 00547 00548 00549 00550 00551 00552 00553 00554 00555 00556 00557 00558 00559 00560 00561 00562 //#define SPI_SOFT 00563 00564 //#if defined (SPI_SOFT) 00565 00566 /***************************************************** 00567 ****************************************************** 00568 TODO: EXPLAIN SOFTWARE SPI 00569 ******************************************************* 00570 ******************************************************/ 00571 00572 /***************************************************** 00573 Software SPI 00574 ******************************************************/ 00575 00576 // Define ports, pins, and data direction registers for set up 00577 /*#define MOSI_PORT PORTB 00578 #define MOSI_PORT_PIN PORTB2 00579 #define MOSI_DDR DDRB 00580 #define MOSI_PORT_PINS PINB 00581 00582 #define MISO_PORT PORTB 00583 #define MISO_PORT_PIN PORTB1 00584 #define MISO_DDR DDRB 00585 #define MISO_PORT_PINS PINB 00586 00587 #define SCLK_PORT PORTD 00588 #define SCLK_PORT_PIN PORTD7 00589 #define SCLK_DDR DDRD 00590 00591 #define SS_PORT PORTB 00592 #define SS_PORT_PIN PORTB0 00593 #define SS_DDR DDRB 00594 00595 00596 // Move bitwise operations to macros to 00597 // help keep folks heads from exploding 00598 #define spi_soft_clear_ss() SS_PORT &= ~(1<<SS_PORT_PIN) 00599 #define spi_soft_set_ss() SS_PORT |= (1<<SS_PORT_PIN) 00600 #define spi_soft_set_mosi_bit() MOSI_PORT |= (1<<MOSI_PORT_PIN) 00601 #define spi_soft_clear_mosi_bit() MOSI_PORT &= ~(1<<MOSI_PORT_PIN) 00602 00603 #define is_bit_set(myVar, i) (!!(myVar & (1 << i))) 00604 00605 // Return the data pin state 00606 uint8_t spi_soft_get_miso_bit(void); 00607 00608 // Return the data pin state 00609 uint8_t spi_soft_get_miso_pin(void); 00610 00611 // Turn the clock line 0 to 1 00612 void spi_soft_toggle_sclk(void); 00613 00614 // Initialize the SPI I/O pins 00615 void spi_soft_setup_pins(void); 00616 00617 00618 #elif defined (SPI_HARD)*/ 00619 /***************************************************** 00620 ****************************************************** 00621 TODO: EXPLAIN SOFTWARE SPI 00622 ******************************************************* 00623 ******************************************************/ 00624 00625 /***************************************************** 00626 Hardware SPI 00627 ******************************************************/ 00628 00629 00630 //#elif defined (SPI_USI) 00631 /***************************************************** 00632 ****************************************************** 00633 TODO: EXPLAIN USI SPI 00634 ******************************************************* 00635 ******************************************************/ 00636 00637 /***************************************************** 00638 USI SPI 00639 ******************************************************/ 00640 00641 00642 //#elif defined (SPI_HARD) 00643 /***************************************************** 00644 ****************************************************** 00645 TODO: EXPLAIN HARDWARE SPI 00646 ******************************************************* 00647 ******************************************************/ 00648 00649 /***************************************************** 00650 Hardware SPI 00651 ******************************************************/ 00652 00653 00654 //#elif defined (SPI_USART) 00655 /***************************************************** 00656 ****************************************************** 00657 TODO: EXPLAIN USART SPI 00658 ******************************************************* 00659 ******************************************************/ 00660 00661 /***************************************************** 00662 USART SPI 00663 ******************************************************/ 00664 00665 //#else 00666 // #error "no SPI type declared" 00667 //#endif 00668 00669 00670 00671 00672 #endif // SPI_H