PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spi_master_revstring.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #include "pic24_all.h"
31 
32 /** \file
33  * SPI example: PIC24 uC in Master mode talking to a PIC24 uC in slave mode, using
34  * the slave PIC24 uC (spi_slave_revstring.c) to reverse strings. The master
35  * expects the slave to assert a PIO output (SLAVE_ORDY in code) when a string
36  * has been reversed; the master then reads the string from the slave.
37 */
38 
39 #define CONFIG_SLAVE_ENABLE() CONFIG_RB3_AS_DIG_OUTPUT()
40 #define SLAVE_ENABLE() _LATB3 = 0 //low true assertion
41 #define SLAVE_DISABLE() _LATB3 = 1
42 
43 #define CONFIG_SLAVE_ORDY() CONFIG_RB2_AS_DIG_INPUT()
44 #define SLAVE_ORDY _RB2
45 
46 void configSPI1(void) {
47  //spi clock = 40MHz/1*4 = 40MHz/4 = 10MHz
48  SPI1CON1 = SEC_PRESCAL_1_1 | //1:1 secondary prescale
49  PRI_PRESCAL_4_1 | //4:1 primary prescale
50  CLK_POL_ACTIVE_HIGH | //clock active high (CKP = 0)
51  SPI_CKE_ON | //out changes active to inactive (CKE=1)
52  SPI_MODE8_ON | //8-bit mode
53  MASTER_ENABLE_ON; //master mode
54 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
55  //nothing to do here. On this family, the SPI1 port uses dedicated
56  //pins for higher speed. The SPI2 port can be used with remappable pins.
57 #else
58  CONFIG_SDO1_TO_RP(6); //use RP6 for SDO
59  CONFIG_RP6_AS_DIG_PIN(); //Ensure that this is a digital pin
60  CONFIG_SCK1OUT_TO_RP(7); //use RP7 for SCLK
61  CONFIG_RP7_AS_DIG_PIN(); //Ensure that this is a digital pin
62  CONFIG_SDI1_TO_RP(5); //use RP5 for SDI
63  CONFIG_RP5_AS_DIG_PIN(); //Ensure that this is a digital pin
64 #endif
65  CONFIG_SLAVE_ENABLE(); //slave select config
66  CONFIG_SLAVE_ORDY(); //output ready from slave
67  SLAVE_DISABLE(); //disable slave
68  SPI1STATbits.SPIEN = 1; //enable SPI mode
69 }
70 
71 typedef enum {
72  STATE_GET_IN_STRING = 0,
73  STATE_GET_REV_STRING,
74 } STATE;
75 
76 void sendStringSPI1(char* psz_s1) {
77  SLAVE_ENABLE();
78  while (*psz_s1) {
79  ioMasterSPI1(*psz_s1);
80  psz_s1++;
81  }
82  ioMasterSPI1(*psz_s1); //send null terminator
83  SLAVE_DISABLE();
84 }
85 
86 void getStringSPI1(char* psz_s1, uint16_t u16_maxCount) {
87  uint16_t u16_i = 0;
88  if (!u16_maxCount) return;
89  SLAVE_ENABLE();
90  do {
91  *psz_s1 = ioMasterSPI1(0); //send dummy byte to get byte back
92  psz_s1++;
93  u16_i++;
94  } while (*(psz_s1-1) && (u16_i <u16_maxCount));
95  SLAVE_DISABLE();
96  psz_s1--;
97  *psz_s1 = 0; //ensure string is null terminated
98 }
99 
100 
101 #define BUFSIZE 63
102 char sz_1[BUFSIZE+1];
103 
104 int main (void) {
105  STATE e_mystate;
106  configBasic(HELLO_MSG);
107  configSPI1();
108  e_mystate = STATE_GET_IN_STRING;
109  while (1) {
110  switch (e_mystate) {
111  case STATE_GET_IN_STRING:
112  inStringEcho(sz_1,BUFSIZE); //get a string from the console
113  if (*sz_1) {
114  sendStringSPI1(sz_1);
115  e_mystate = STATE_GET_REV_STRING;
116  }
117  break;
118  case STATE_GET_REV_STRING:
119  if (SLAVE_ORDY) {
120  getStringSPI1(sz_1,BUFSIZE+1);
121  outString(sz_1); //output the reversed string
122  outString("\n");
123  e_mystate = STATE_GET_IN_STRING;
124  }
125  break;
126  default:
127  e_mystate = STATE_GET_IN_STRING;
128  }
129  doHeartbeat();
130  } //end switch
131 }