PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
reflow_flash.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 #include "pic24_all.h"
30 #include <stdio.h>
31 #include "reflow_oven.h"
32 
33 /** \file
34 Utilities for storing/reading reflow oven power versus temperature calibration
35 data to/from flash memory.
36 */
37 
38 UFDATA fdata;
39 
40 const PROFILE profiles[NUM_PROFILES] = {
41  {100,100,150,100,230,90,20,90,60, 183},
42  {150,100,200,100,250,90,30,90,60, 217}
43 };
44 
45 uint8_t u8_currentProfile = 0;
46 
47 
48 void doCommit(UFDATA* p_ufdata) {
49  union32 u_memaddr;
50  u_memaddr.u32 = DATA_FLASH_PAGE;
51  doWritePageFlash(u_memaddr, (uint8_t *) p_ufdata, FLASH_DATA_SIZE);
52 }
53 
54 void doRead(UFDATA* p_ufdata) {
55  union32 u_memaddr;
56  u_memaddr.u32 = DATA_FLASH_PAGE;
57  doReadPageFlash(u_memaddr, (uint8_t *) p_ufdata, FLASH_DATA_SIZE);
58 }
59 
60 char *getProfileDesc(uint8_t u8_p) {
61  if (u8_p == LEADTIN) return("Lead(40%)/Tin (60%) mix");
62  else return("Lead-free");
63 }
64 
65 
66 void printProfile (uint8_t u8_p) {
67  float f_ramp;
68 
69  if (u8_p == LEADTIN)
70  printf("%s profile, Wet temp: %d C \n",
71  getProfileDesc(u8_p),
72  profiles[u8_p].i16_wetTemp);
73  else printf("%s profile, Wet temp: %d C \n",
74  getProfileDesc(u8_p),
75  profiles[u8_p].i16_wetTemp);
76  f_ramp = (float) (profiles[u8_p].i16_preheatTemp - 25.0)/(float)profiles[u8_p].u16_preheatTime;
77  printf("Preheat Temp: %d C, Time: %d s, Ramp: %6.2f (C/s)\n",
78  profiles[u8_p].i16_preheatTemp,
79  profiles[u8_p].u16_preheatTime,
80  (double) f_ramp);
81  f_ramp = (profiles[u8_p].i16_soakTemp - profiles[u8_p].i16_preheatTemp)/(float)profiles[u8_p].u16_soakTime;
82  printf("Soak Temp: %d C, Time: %d s, Ramp: %6.2f (C/s)\n",
83  profiles[u8_p].i16_soakTemp,
84  profiles[u8_p].u16_soakTime,
85  (double) f_ramp);
86  f_ramp = (float)(profiles[u8_p].i16_reflowTemp - profiles[u8_p].i16_soakTemp)/(float)profiles[u8_p].u16_reflowTime;
87  printf("Reflow Temp: %d C, Time: %d s, Ramp: %6.2f (C/s), Hold time: %d\n",
88  profiles[u8_p].i16_reflowTemp,
89  profiles[u8_p].u16_reflowTime,
90  (double) f_ramp,
91  profiles[u8_p].u16_reflowHoldTime);
92 
93  f_ramp = (float)(profiles[u8_p].i16_reflowTemp - profiles[u8_p].i16_coolTemp)/(float)profiles[u8_p].u16_coolTime;
94  printf("Cool1 Temp: %d C, Time: %d s, Ramp: %6.2f (C/s)\n",
95  profiles[u8_p].i16_coolTemp,
96  profiles[u8_p].u16_coolTime,
97  (double) f_ramp);
98 
99 
100 }
101 
102 #define SETTLE_TIME 15 //seconds
103 
104 static inline void DELAY_SECONDS(uint8_t u8_s) {
105  while (u8_s) {
106  DELAY_MS(1000);
107  u8_s--;
108  }
109 }
110 
111 void doTempCal(void) {
112  uint8_t u8_c, u8_i;
113  uint16_t tempC;
114 
115  u8_currPowerSetting = 0;
116  printf("Warning: Oven must be at room temperature and door closed to do calibration.\n");
117  printf("Warning: This takes 30 minutes! Do you still want to continue? (y/n): ");
118  u8_c = inCharEcho();
119  if (u8_c != 'y') return;
120  tempC = getCelsiusI16Temp();
121  if ((tempC < 20) || (tempC > 40)) {
122  printf("\nTemperature is %u; it is not between 20C and 40C, something is wrong, aborting...\n",
123  tempC);
124  return;
125  }
126  fdata.caldata.temp[0] = tempC;
127  printf("\nRoom temperature is: %uC\n", tempC);
128  printf("Beginning calibration...hit any key to exit.\n");
129  for (u8_i = 1; u8_i <= 100; u8_i++) {
130  u8_currPowerSetting++;
131  DELAY_SECONDS(SETTLE_TIME);
132  tempC = getCelsiusI16Temp();
133  fdata.caldata.temp[u8_i] = tempC;
134  printf("Power: %u, Temp: %u \n",u8_i, tempC);
135  if (isCharReady()) break;
136  if (tempC > MAX_TEMP) break;
137  }
138  u8_currPowerSetting = 0;
139  if (isCharReady()) u8_c = inCharEcho();
140  while (u8_i <= 100) {
141  fdata.caldata.temp[u8_i] = tempC;
142  u8_i++;
143  }
144  doCommit(&fdata);
145  printf("Calibration data written.\n");
146 }
147 
148 void printTempCal(void) {
149  uint8_t u8_i;
150  printf("\nPower Setting Temp (C)\n");
151  for (u8_i=0; u8_i <= 100; u8_i++) {
152  printf(" %d %u\n",
153  u8_i, fdata.caldata.temp[u8_i]);
154  }
155 }
156 
157 uint8_t printProfileMenu(void) {
158  printf("\n1 Print Tin/Lead mix profile\n");
159  printf("2 Print Lead-free profile\n");
160  printf("3 Print temperature calibration data\n");
161  printf("4 Perform temperature calibration and commit to flash\n");
162  printf("5 Toggle Profile\n");
163  printf("6 Exit\n");
164  printf(" Enter number (1-6): ");
165  return inCharEcho();
166 }
167 
168 
169 void doProfileMenu(void) {
170  uint8_t u8_c;
171 
172  do {
173  u8_c = printProfileMenu();
174  printf("\n");
175  switch (u8_c) {
176  case '1':
177  printProfile(0);
178  break;
179  case '2':
180  printProfile(1);
181  break;
182  case '3':
183  printTempCal();
184  break;
185  case '4':
186  doTempCal();
187  break;
188  case '5':
189  u8_currentProfile =!u8_currentProfile;
190  printf("Current profile: %s\n", getProfileDesc(u8_currentProfile));
191  break;
192  } //end switch
193  } while (u8_c != '6');
194 }
195 
196