PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
app_ds1631.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 /** \file
31  * ESOS application program to demonstrate I2C mastering in ESOS.
32  * Application recreates code in \ref ds1631_i2c.c in Figure 10.52.
33  * (See Figure 10.49 in the text for circuit.)
34  *
35  * Application also has a flashing LED on RB15. Flashing LED is generated
36  * by an <em>software timer</em> calling a user-provided callback function.
37  *
38  * \note Demonstrates child tasks, ESOS software timers, and I2C service
39  */
40 
41 
42 // INCLUDEs go here (First include the main esos.h file)
43 // After that, the user can include what they need
44 #include "esos.h"
45 #ifdef __linux
46 #include "esos_pc.h"
47 #include "esos_pc_stdio.h"
48 // INCLUDE these so that printf() and our PC hacks work
49 #include <stdio.h>
50 #include <sys/select.h>
51 #include <termios.h>
52 #include <unistd.h>
53 #else
54 #include "esos_pic24.h"
55 #include "esos_pic24_rs232.h"
56 #include "esos_pic24_i2c.h"
57 #include <stdio.h>
58 #endif
59 
60 // DEFINEs go here
61 #define DS1631ADDR 0x90 //DS1631 address with all pins tied low
62 #define ACCESS_CONFIG 0xAC
63 #define CONFIG_COMMAND 0x0C //continuous conversion, 12-bit mode
64 #define START_CONVERT 0x51
65 #define READ_TEMP 0xAA
66 
67 #ifndef __linux
68 #define CONFIG_LED1() CONFIG_RB15_AS_DIG_OUTPUT()
69 #define LED1 _LATB15
70 #else
71 #define CONFIG_LED1() printf("called CONFIG_LED1()\n");
72 uint8_t LED1 = TRUE; // LED1 is initially "on"
73 #endif
74 
75 // PROTOTYPEs go here
76 
77 // GLOBALs go here
78 // Generally, the user-created semaphores will be defined/allocated here
79 char psz_CRNL[3]= {0x0D, 0x0A, 0};
80 char psz_prompt[] = "Temp is ";
81 char psz_done[9]= {' ','D','O','N','E','!',0x0D, 0x0A, 0};
82 int16_t i16_temp;
83 UINT16 U16_raw;
84 
85 ESOS_SEMAPHORE(sem_dataReady);
86 ESOS_SEMAPHORE(sem_dataPrinted);
87 ESOS_SEMAPHORE(sem_ds1631Ready);
88 
89 #ifdef __linux
90 /*
91  * Simulate the timer ISR found on a MCU
92  * The PC doesn't have a timer ISR, so this task will periodically
93  * call the timer services callback instead.
94  * USED ONLY FOR DEVELOPMENT AND TESTING ON PC.
95  * Real MCU hardware doesn't need this task
96  */
97 ESOS_USER_TASK( __simulated_isr ) {
99  while (TRUE) {
100  // call the ESOS timer services callback just like a real H/W ISR would
101  __esos_tmrSvcsExecute();
103 
104  } // endof while(TRUE)
105  ESOS_TASK_END();
106 } // end child_task
107 #endif
108 
109 /************************************************************************
110  * User supplied functions
111  ************************************************************************
112  */
113 
114 /*
115  * An ESOS software timer callback function strobe the heartbeat LED.
116  *
117  * Toggles LED1 everytime the callback is called. Exact period is
118  * determined by application when this timer callback function is
119  * registered with ESOS. See \ref esos_RegisterTimer
120  * Application can change timer period on-the-fly with \ref esos_ChangeTimerPeriod
121  *
122  * \note Since this heartbeat is performed in an ESOS software
123  * timer callabck, a flashing LED indicates that the ESOS system
124  * tick ISR is being called properly. If the LED quits flashing,
125  * then the ESOS system tick has ceased working. This probably indicates
126  * some catastrophic failure of the system. However, the cause could
127  * be poorly-behaved user code that is manipulating the hardware registers
128  * with the timer or interrupt enables directly. ESOS provides functions
129  * to change state of interrupts and user code should never modify the
130  * hardware used by ESOS to implement the system tick.
131  * \hideinitializer
132  */
133 
134 // user-created timer callback
135 ESOS_USER_TIMER( swTimerLED ) {
136  LED1 = !LED1;
137 #ifdef __linux
138  if (LED1) {
139  printf("\a");
140  fflush(stdout);
141  }
142 #endif
143 } //endof swTimerLED
144 
145 /*
146  * user task to setup DS1631 for continuous temperature
147  * conversion. Will signal when DS1631 is ready to be
148  * used.
149  */
150 ESOS_USER_TASK(start_ds1631) {
151  ESOS_TASK_BEGIN();
153  ESOS_TASK_WAIT_ON_WRITE2I2C1(DS1631ADDR, ACCESS_CONFIG, CONFIG_COMMAND);
154  ESOS_TASK_WAIT_ON_WRITE1I2C1(DS1631ADDR, START_CONVERT);
156  ESOS_SIGNAL_SEMAPHORE(sem_ds1631Ready, 1);
157  ESOS_TASK_END();
158 } //end task start_ds1631
159 
160 /*
161  * user task to read DS1631 every 3/4 second
162  * will signal when data has been successfully read
163  */
164 ESOS_USER_TASK(read_ds1631) {
165  static uint8_t u8_lo, u8_hi;
166 
167  ESOS_TASK_BEGIN();
168  ESOS_TASK_WAIT_SEMAPHORE(sem_ds1631Ready, 1);
169  while (TRUE) {
170  ESOS_TASK_WAIT_ON_WRITE1I2C1(DS1631ADDR, READ_TEMP);
171  ESOS_TASK_WAIT_ON_READ2I2C1(DS1631ADDR, u8_hi, u8_lo);
172  U16_raw.u8Msb = u8_hi;
173  U16_raw.u8Lsb = u8_lo;
174  i16_temp = u8_hi;
175  i16_temp = ((i16_temp<<8)|u8_lo);
176  ESOS_SIGNAL_SEMAPHORE(sem_dataReady, 1);
178  ESOS_TASK_WAIT_SEMAPHORE(sem_dataPrinted, 1);
179  } //end while()
180  ESOS_TASK_END();
181 } //end task read_ds1631
182 
183 /*
184  * User task to display temperature results from DS1631.
185  * Used printf and floating point for convenience. A
186  * production application would likely create custom functions
187  * to avoid including these huge libraries.
188  */
189 ESOS_USER_TASK(update) {
190  float f_tempC, f_tempF;
191 
192  ESOS_TASK_BEGIN();
193  while (TRUE) {
194  ESOS_TASK_WAIT_SEMAPHORE(sem_dataReady, 1);
195  f_tempC = (float) i16_temp; //convert to floating point
196  f_tempC = f_tempC/256; //divide by precision
197  f_tempF = f_tempC*9/5 + 32;
198  printf("Temp is: 0x%0X, %4.4f (C), %4.4f (F)\n", i16_temp, (double) f_tempC, (double) f_tempF);
199  ESOS_SIGNAL_SEMAPHORE(sem_dataPrinted, 1);
200  } // end while(TRUE)
201  ESOS_TASK_END();
202 } // end update()
203 
204 /****************************************************
205  * user_init()
206  ****************************************************
207  */
208 void user_init(void) {
209 
210  // Call the hardware-provided routines to print the
211  // HELLO_MSG to the screen. Must use this call because
212  // the ESOS communications subsystems is not yet fully
213  // initialized, since this call is in user_init()
214  //
215  // In general, users should call hardware-specific
216  // function like this.
217  __esos_unsafe_PutString( HELLO_MSG );
218 
219 #ifdef __linux
220  // register our little ESOS task to mimic MCU's TIMER T1 IRQ which kicks off
221  // the ESOS S/W timers when they expire
222  esos_RegisterTask( __simulated_isr );
223 #endif
224 
225  // configure our hardware to support to support our application
226  CONFIG_LED1();
227  esos_pic24_configI2C1(400); //configure I2C for 400 KHz
228 
229  ESOS_INIT_SEMAPHORE(sem_ds1631Ready, 0);
230  ESOS_INIT_SEMAPHORE(sem_dataReady, 0);
231  ESOS_INIT_SEMAPHORE(sem_dataPrinted, 0);
232 
233  // user_init() should register at least one user task
234  esos_RegisterTask(start_ds1631);
235  esos_RegisterTask(read_ds1631);
236  esos_RegisterTask(update);
237 
238  // register our callback function with ESOS to create a software timer
239  esos_RegisterTimer( swTimerLED, 250);
240 
241 } // end user_init()