##// END OF EJS Templates
codigo inicial de saigd (software de embebido) y timeEngined (firmware de tarjeta timeEngine)
aaguilar -
r132:133
parent child
Show More
@@ -0,0 +1,60
1 /*
2 * channel.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "channel.h"
9
10 channel::channel():
11 chn_id(0),chn_name{"\0"},chn_gain(0),
12 chn_baudrate(0),chn_status(0)
13 {
14 // TODO Auto-generated constructor stub
15
16 }
17
18 channel::~channel() {
19 // TODO Auto-generated destructor stub
20 }
21
22 uint8_t channel::chn_get_id(void){
23 return 1;
24 }
25
26 const char* channel::chn_get_name(void){
27 return "";
28 }
29
30 uint8_t channel::chn_get_gain(void){
31 return 1;
32 }
33
34 uint32_t channel::chn_get_baudrate(void){
35 return 1;
36 }
37
38 uint8_t channel::chn_get_status(void){
39 return 1;
40 }
41
42 bool channel::chn_set_id(uint8_t){
43 return true;
44 }
45
46 bool channel::chn_set_name(const char*){
47 return true;
48 }
49
50 bool channel::chn_set_gain(uint8_t){
51 return true;
52 }
53
54 bool channel::chn_set_baudrate(uint32_t){
55 return true;
56 }
57
58 bool channel::chn_set_status(uint8_t){
59 return true;
60 }
@@ -0,0 +1,37
1 /*
2 * channel.h
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef CHANNEL_H_
9 #define CHANNEL_H_
10
11 #include "../utils/defs.h"
12
13 class channel {
14 public:
15 channel();
16 virtual ~channel();
17
18 uint8_t chn_get_id(void);
19 const char* chn_get_name(void);
20 uint8_t chn_get_gain(void);
21 uint32_t chn_get_baudrate(void);
22 uint8_t chn_get_status(void);
23 bool chn_set_id(uint8_t);
24 bool chn_set_name(const char*);
25 bool chn_set_gain(uint8_t);
26 bool chn_set_baudrate(uint32_t);
27 bool chn_set_status(uint8_t);
28
29 private:
30 uint8_t chn_id;
31 char chn_name[4];
32 uint8_t chn_gain;
33 uint32_t chn_baudrate;
34 uint8_t chn_status;
35 };
36
37 #endif /* CHANNEL_H_ */
@@ -0,0 +1,62
1 /*
2 * processEnginectrl.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "processEnginectrl.h"
9
10 processEngine_ctrl::processEngine_ctrl():
11 pdtpkg(nullptr),pe_chns(nullptr){
12 // TODO Auto-generated constructor stub
13
14 }
15
16 processEngine_ctrl::~processEngine_ctrl() {
17 // TODO Auto-generated destructor stub
18 }
19
20 bool processEngine_ctrl::peCtrl_initialization(void*){
21 return true;
22 }
23
24 bool processEngine_ctrl::peCtrl_chn_activate(void*){
25 return true;
26 }
27
28 bool processEngine_ctrl::peCtrl_chn_deactivate(void*){
29 return true;
30 }
31
32 bool processEngine_ctrl::peCtrl_chn_set_decimation(void*){
33 return true;
34 }
35
36 bool processEngine_ctrl::peCtrl_chn_set_baudrate(void*){
37 return true;
38 }
39
40 bool processEngine_ctrl::peCtrl_chn_get_information(void*){
41 return true;
42 }
43
44 bool processEngine_ctrl::peCtrl_chn_set_param(void*){
45 return true;
46 }
47
48 bool processEngine_ctrl::peCtrl_chn_get_param(void*){
49 return true;
50 }
51
52 bool processEngine_ctrl::peCtrl_start_acquition(void*){
53 return true;
54 }
55
56 bool processEngine_ctrl::peCtrl_stop_acquisition(void*){
57 return true;
58 }
59
60 bool processEngine_ctrl::peCtrl_get_new_data(void*){
61 return true;
62 }
@@ -0,0 +1,36
1 /*
2 * processEnginectrl.h
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef PROCESSENGINECTRL_H_
9 #define PROCESSENGINECTRL_H_
10
11 #include "../utils/defs.h"
12 #include "channel.h"
13
14 class processEngine_ctrl {
15 public:
16 processEngine_ctrl();
17 virtual ~processEngine_ctrl();
18
19 bool peCtrl_initialization(void*);
20 bool peCtrl_chn_activate(void*);
21 bool peCtrl_chn_deactivate(void*);
22 bool peCtrl_chn_set_decimation(void*);
23 bool peCtrl_chn_set_baudrate(void*);
24 bool peCtrl_chn_get_information(void*);
25 bool peCtrl_chn_set_param(void*);
26 bool peCtrl_chn_get_param(void*);
27 bool peCtrl_start_acquition(void*);
28 bool peCtrl_stop_acquisition(void*);
29 bool peCtrl_get_new_data(void*);
30
31 private:
32 pe_data_pkg* pdtpkg;
33 channel *pe_chns;
34 };
35
36 #endif /* PROCESSENGINECTRL_H_ */
@@ -0,0 +1,35
1 /*
2 * saigctrl.cpp
3 *
4 * Created on: Oct 15, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "saigctrl.h"
9
10 saig_ctrl::saig_ctrl():
11 pdtpkg(nullptr){
12 // TODO Auto-generated constructor stub
13
14 }
15
16 saig_ctrl::~saig_ctrl() {
17 // TODO Auto-generated destructor stub
18 }
19
20 bool saig_ctrl::saig_get_te_tm_pkg(te_time_pkg* tmpkg){
21 return true;
22 }
23
24 bool saig_ctrl::saig_get_pe_data_pkg(pe_data_pkg* pdatapkg){
25 return true;
26 }
27
28 bool saig_ctrl::saig_merge_tm_data_pkgs(saig_data_pkg* sdatapkg,
29 te_time_pkg* tmpkg, pe_data_pkg* pdatpkg){
30 return true;
31 }
32
33 bool saig_ctrl::saig_send_data_pkg(saig_data_pkg* sdatapkg){
34 return true;
35 }
@@ -0,0 +1,29
1 /*
2 * saigctrl.h
3 *
4 * Created on: Oct 15, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef SAIGCTRL_H_
9 #define SAIGCTRL_H_
10
11 #include "../processEngine/processEnginectrl.h"
12 #include "../timeEngine/timeEnginectrl.h"
13 #include "../utils/defs.h"
14
15 class saig_ctrl {
16 public:
17 saig_ctrl();
18 virtual ~saig_ctrl();
19
20 bool saig_get_te_tm_pkg(te_time_pkg*);
21 bool saig_get_pe_data_pkg(pe_data_pkg*);
22 bool saig_merge_tm_data_pkgs(saig_data_pkg*, te_time_pkg*, pe_data_pkg*);
23 bool saig_send_data_pkg(saig_data_pkg*);
24
25 private:
26 saig_data_pkg * pdtpkg;
27 };
28
29 #endif /* SAIGCTRL_H_ */
@@ -0,0 +1,19
1 /*
2 * saigd.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 //#include <sp.h>
9 //#include <sp_func.h>
10 #include "utils/uart.h"
11
12 rbp::uart *puartport;
13
14 int main() {
15
16 //SP_connect();
17
18 return 0;
19 }
@@ -0,0 +1,19
1 /*
2 * clockctrl.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "clockctrl.h"
9
10 clock_ctrl::clock_ctrl():
11 clk_config(NULL),clk_state(NULL){
12 // TODO Auto-generated constructor stub
13
14 }
15
16 clock_ctrl::~clock_ctrl() {
17 // TODO Auto-generated destructor stub
18 }
19
@@ -0,0 +1,26
1 /*
2 * clockctrl.h
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef TIMEENGINE_CLOCKCTRL_H_
9 #define TIMEENGINE_CLOCKCTRL_H_
10
11 #include "../utils/defs.h"
12
13 class clock_ctrl {
14 public:
15 clock_ctrl();
16 virtual ~clock_ctrl();
17
18 bool clockCtrl_configure(void*);
19 bool clockCtrl_get_state(void*);
20
21 private:
22 clock_config_struct* clk_config;
23 clock_state_struct* clk_state;
24 };
25
26 #endif /* TIMEENGINE_CLOCKCTRL_H_ */
@@ -0,0 +1,51
1 /*
2 * gnssctrl.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "gnssctrl.h"
9 #include "../utils/uart.h"
10
11 extern rbp::uart *puartport;
12
13 gnss_ctrl::gnss_ctrl():
14 gnss_config(NULL),gnss_prcstm(NULL),cmd(0){
15 // TODO Auto-generated constructor stub
16
17 }
18
19 gnss_ctrl::~gnss_ctrl() {
20 // TODO Auto-generated destructor stub
21 }
22
23 bool gnss_ctrl::gnssCtrl_power_on(void*){
24 if( puartport->transmit(cmd[GNSSPOWER_ON], 1) != 1){
25 return false;
26 }
27 return true;
28 }
29
30 bool gnss_ctrl::gnssCtrl_power_off(void*){
31 if( puartport->transmit(cmd[GNSSPOWER_OFF], 1) != 1){
32 return false;
33 }
34 return true;
35 }
36
37 bool gnss_ctrl::gnssCtrl_configure(void*){
38 return true;
39 }
40
41 bool gnss_ctrl::gnssCtrl_sync_pps(void*){
42 return true;
43 }
44
45 bool gnss_ctrl::gnssCtrl_get_time_info(void*){
46 return true;
47 }
48
49 bool gnss_ctrl::gnssCtrl_is_locked(void*){
50 return true;
51 }
@@ -0,0 +1,32
1 /*
2 * gnssctrl.h
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef TIMEENGINE_GNSSCTRL_H_
9 #define TIMEENGINE_GNSSCTRL_H_
10
11 #include "../utils/defs.h"
12
13 class gnss_ctrl {
14 public:
15 gnss_ctrl();
16 virtual ~gnss_ctrl();
17
18 bool gnssCtrl_power_on(void*);
19 bool gnssCtrl_power_off(void*);
20 bool gnssCtrl_configure(void*);
21 bool gnssCtrl_sync_pps(void*);
22 bool gnssCtrl_get_time_info(void*);
23 bool gnssCtrl_is_locked(void*);
24
25 private:
26 gnss_config_struct* gnss_config;
27 gnss_precise_time* gnss_prcstm;
28
29 uint8_t** cmd;
30 };
31
32 #endif /* TIMEENGINE_GNSSCTRL_H_ */
@@ -0,0 +1,74
1 /*
2 * gnss_info.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "gnss_info.h"
9 #include <ctime>
10 #include <cstring>
11
12 gnss_info::gnss_info():
13 smask(0),PDOP(0),HDOP(0),VDOP(0),
14 lat(0),lon(0),elv(0),speed(0),
15 direction(0),declination(0){
16 memset(&satinfo,0,sizeof(gnss_satinfo));
17 gnss_time_now();
18 sig = NMEA_SIG_BAD;
19 fix = NMEA_FIX_BAD;
20 }
21
22 gnss_info::~gnss_info() {
23 // TODO Auto-generated destructor stub
24 }
25
26 void gnss_info::gnss_time_now() {
27 time_t lt;
28 struct tm *tt;
29 time(&lt);
30 tt = gmtime(&lt);
31 utc.year = tt->tm_year;
32 utc.mon = tt->tm_mon;
33 utc.day = tt->tm_mday;
34 utc.hour = tt->tm_hour;
35 utc.min = tt->tm_min;
36 utc.sec = tt->tm_sec;
37 utc.hsec = 0;
38 }
39
40 void gnss_info::set_utc(gnss_time* t,int f) {
41 if( f & NMEA_TIME ){
42 utc.hour = t->hour;
43 utc.min = t->min;
44 utc.sec = t->sec;
45 utc.hsec = t->hsec;
46 }
47 if( f & NMEA_DATE ){
48 utc.year = t->year;
49 utc.mon = t->mon;
50 utc.day = t->day;
51 }
52 }
53
54 void gnss_info::get_utc(gnss_time* t) {
55 memcpy((void*)t,(void*)&utc,sizeof(gnss_time));
56 }
57
58 void gnss_info::set_pos(gnss_pos* p) {
59 lat = p->lat;
60 lon = p->lon;
61 }
62
63 void gnss_info::get_pos(gnss_pos* p) {
64 p->lat = lat;
65 p->lon = lon;
66 }
67
68 void gnss_info::set_satinfo(gnss_satinfo* si) {
69
70 }
71
72 void gnss_info::get_satinfo(gnss_satinfo* si) {
73
74 }
@@ -0,0 +1,167
1 /*
2 * gnss_info.h
3 * based on:
4 *
5 * NMEA library
6 * URL: http://nmea.sourceforge.net
7 * Author: Tim (xtimor@gmail.com)
8 * Licence: http://www.gnu.org/licenses/lgpl.html
9 * $Id: info.h 10 2007-11-15 14:50:15Z xtimor $
10 *
11 * Modified on: Oct 29, 2014
12 * Author: Alan Aguilar Sologuren
13 */
14
15 #ifndef GNSS_INFO_H_
16 #define GNSS_INFO_H_
17
18
19 #define NMEA_SIG_BAD (0)
20 #define NMEA_SIG_LOW (1)
21 #define NMEA_SIG_MID (2)
22 #define NMEA_SIG_HIGH (3)
23
24 #define NMEA_FIX_BAD (1)
25 #define NMEA_FIX_2D (2)
26 #define NMEA_FIX_3D (3)
27
28 #define NMEA_MAXSAT (12)
29 #define NMEA_SATINPACK (4)
30 #define NMEA_NSATPACKS (NMEA_MAXSAT / NMEA_SATINPACK)
31
32 #define NMEA_DEF_LAT (5001.2621)
33 #define NMEA_DEF_LON (3613.0595)
34
35
36 #define NMEA_TIME 0x1
37 #define NMEA_DATE 0x2
38 /**
39 * Position data in fractional degrees or radians
40 */
41 typedef struct _gnss_pos
42 {
43 double lat; /**< Latitude */
44 double lon; /**< Longitude */
45
46 } gnss_pos;
47
48
49 /**
50 * Date and time data
51 * @see gnss_time_now
52 */
53 typedef struct _gnss_time
54 {
55 int year; /**< Years since 1900 */
56 int mon; /**< Months since January - [0,11] */
57 int day; /**< Day of the month - [1,31] */
58 int hour; /**< Hours since midnight - [0,23] */
59 int min; /**< Minutes after the hour - [0,59] */
60 int sec; /**< Seconds after the minute - [0,59] */
61 int hsec; /**< Hundredth part of second - [0,99] */
62
63 } gnss_time;
64
65
66 /**
67 * Information about satellite
68 * @see gnss_satinfo
69 * @see nmeaGPGSV
70 */
71 typedef struct _gnss_sat
72 {
73 int id; /**< Satellite PRN number */
74 int in_use; /**< Used in position fix */
75 int elv; /**< Elevation in degrees, 90 maximum */
76 int azimuth; /**< Azimuth, degrees from true north, 000 to 359 */
77 int sig; /**< Signal, 00-99 dB */
78
79 } gnss_sat;
80
81
82 /**
83 * Information about all satellites in view
84 * @see gnss_info
85 * @see nmeaGPGSV
86 */
87 typedef struct _gnss_satinfo
88 {
89 int inuse; /**< Number of satellites in use (not those in view) */
90 int inview; /**< Total number of satellites in view */
91 gnss_sat sat[NMEA_MAXSAT]; /**< Satellites information */
92
93 } gnss_satinfo;
94
95
96
97
98
99 /**
100 * Summary GPS information from all parsed packets,
101 * used also for generating NMEA stream
102 * @see gnss_parse
103 * @see gnss_GPGGA2info, gnss_...2info
104 */
105 class gnss_info {
106 public:
107 gnss_info();
108 virtual ~gnss_info();
109 void gnss_zero_info(gnss_info *info);
110
111 void set_smask(int m){smask = m;}
112 int get_smask(){return smask;}
113 void set_sig(int s){sig = s;}
114 int get_sig(){return sig;}
115 void set_fix(int f){ fix = f;}
116 int get_fix(){return fix;}
117 void set_pdop(double p){ PDOP = p;}
118 double get_pdop(){return PDOP;}
119 void set_hdop(double h){HDOP = h;}
120 double get_hdop(){return HDOP;}
121 void set_vdop(double v){VDOP = v;}
122 double get_vdop(){return VDOP;}
123 void set_elv(double e){elv = e;}
124 double get_elv(){return elv;}
125 void set_speed(double s){speed = s;}
126 double get_speed(){return speed;}
127 void set_direction(double d){direction = d;}
128 double get_direction(){return direction;}
129 void set_declination(double d){declination = d;}
130 double get_declination(){return declination;}
131
132 void set_utc(gnss_time*,int);
133 void get_utc(gnss_time*);
134 void set_pos(gnss_pos*);
135 void get_pos(gnss_pos*);
136 void set_satinfo(gnss_satinfo*);
137 void get_satinfo(gnss_satinfo*);
138
139 private:
140 void gnss_time_now();
141
142 private:
143 int smask; /**< Mask specifying types of packages from which data have been obtained */
144 gnss_time utc; /**< UTC of position */
145 int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
146 int fix; /**< Operating mode, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
147 double PDOP; /**< Position Dilution Of Precision */
148 double HDOP; /**< Horizontal Dilution Of Precision */
149 double VDOP; /**< Vertical Dilution Of Precision */
150 double lat; /**< Latitude in NDEG - +/-[degree][min].[sec/60] */
151 double lon; /**< Longitude in NDEG - +/-[degree][min].[sec/60] */
152 double elv; /**< Antenna altitude above/below mean sea level (geoid) in meters */
153 double speed; /**< Speed over the ground in kilometers/hour */
154 double direction; /**< Track angle in degrees True */
155 double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
156 gnss_satinfo satinfo;/**< Satellites information */
157 };
158
159
160
161
162
163
164
165
166
167 #endif /* GNSS_INFO_H_ */
@@ -0,0 +1,15
1 /*
2 * libnmea++.h
3 *
4 * Created on: Nov 3, 2014
5 * Author: aras
6 */
7
8 #ifndef LIBNMEA___H_
9 #define LIBNMEA___H_
10
11 #include "nmea_code.h"
12 #include "gnss_info.h"
13 #include "parse/code_parser.h"
14
15 #endif /* LIBNMEA___H_ */
@@ -0,0 +1,91
1 /*
2 * nmea_code.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include <cassert>
9 #include <cstring>
10 #include <cstddef>
11 #include "nmea_code.h"
12
13 nmea_code::nmea_code():
14 p_next(NULL),p_prev(NULL),
15 nmeastring(NULL),nmeasplit(NULL),
16 num_params(0){
17
18 }
19
20 nmea_code::~nmea_code() {
21
22 }
23
24 nmea_code& nmea_code::operator <<(nmea_code& pcd) {
25 assert(&pcd!=0);
26 this->p_next = &pcd;
27 pcd.set_prev(this);
28 return pcd;
29 }
30
31 nmea_code& nmea_code::operator >>(nmea_code& pcd) {
32 pcd.set_string(this->nmeastring);
33 pcd.set_next(this->p_next);
34 pcd.set_prev(this->p_prev);
35 return *pcd.prev();
36 }
37
38 bool nmea_code::set_string(const char* strnmea){
39 size_t len = strlen(strnmea);
40 nmeastring = new char[len+1];
41 nmeastring[len] = '\0';
42 strcpy(nmeastring,strnmea);
43 split_code();
44 return true;
45 }
46
47 char* nmea_code::get_string() {
48 size_t len = strlen(nmeastring);
49 char* strnmea = new char[len];
50 strcpy(strnmea,nmeastring);
51 return strnmea;
52 }
53
54 char* nmea_code::get_parameter(int index){
55 if( (index >= 0 ) && ( index < num_params ) )
56 {
57 char *elem = new char[strlen(nmeasplit[index])];
58 strcpy(elem,nmeasplit[index]);
59 return elem;
60 }
61 return NULL;
62 }
63
64
65 void nmea_code::split_code(void) {
66 char* params[20];
67
68 size_t sz = strlen(nmeastring);
69 char* code = new char[sz+1];
70 //code[sz]='\0';
71 strcpy(code,nmeastring);
72
73 code = strtok(code,"$,*");
74 int i=0;
75 while (code != NULL)
76 {
77 sz = strlen(code);
78 params[i] = new char[sz+1];
79 params[i][sz]='\0';
80 strcpy(params[i++],code);
81 code = strtok (NULL, "$,*");
82 }
83 num_params=i;
84 nmeasplit = new char* [i];
85
86 for(int j=0;j<i;j++){
87 nmeasplit[j] = params[j];
88 }
89 }
90
91
@@ -0,0 +1,39
1 /*
2 * nmea_code.h
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef PARSE_NMEA_CODE_H_
9 #define PARSE_NMEA_CODE_H_
10
11 class nmea_code {
12 public:
13 nmea_code();
14 virtual ~nmea_code();
15
16 bool set_string(const char*);
17 char* get_string();
18 char* get_parameter(int);
19
20
21
22 nmea_code* next(void){return p_next;};
23 nmea_code* prev(void){return p_prev;};
24 nmea_code& operator >>(nmea_code&);
25 nmea_code& operator <<(nmea_code&);
26
27 bool set_next(nmea_code* ptr){p_next = ptr; return true;};
28 bool set_prev(nmea_code* ptr){p_prev = ptr; return true;};
29
30 private:
31 nmea_code* p_next;
32 nmea_code* p_prev;
33 char* nmeastring;
34 char** nmeasplit;
35 int num_params;
36 void split_code(void);
37 };
38
39 #endif /* PARSE_NMEA_CODE_H_ */
@@ -0,0 +1,33
1 /*
2 * code_parser.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "code_parser.h"
9 #include <algorithm>
10 #include <string>
11 #include <cstring>
12
13 code_parser::code_parser():
14 parser(NULL){
15 subscribe_nmea_codes(supported_codes);
16 }
17
18 code_parser::~code_parser() {
19
20 }
21
22 bool code_parser::parse_nmea(nmea_code* nc, gnss_info* gi) {
23 std::string cd(nc->get_parameter(0));
24 std::transform(cd.begin(), cd.end(),cd.begin(), ::toupper);
25 parser=supported_codes[cd];
26 if(parser!=NULL)
27 {
28 parser(nc,gi);
29 return true;
30 }
31 return false;
32 }
33
@@ -0,0 +1,29
1 /*
2 * code_parser.h
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef PARSE_CODE_PARSER_H_
9 #define PARSE_CODE_PARSER_H_
10
11 #include "nmea_defs.h"
12 /**
13 * class code_parser
14 * se encarga de decodificar la informacion de una trama NMEA
15 *
16 */
17 class code_parser {
18 public:
19 code_parser();
20 virtual ~code_parser();
21
22 bool parse_nmea(nmea_code*, gnss_info*);
23
24 private:
25 pnmea_parse parser;
26 code supported_codes;
27 };
28
29 #endif /* PARSE_CODE_PARSER_H_ */
@@ -0,0 +1,12
1 /*
2 * gpalm_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int gpalm_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,44
1 /*
2 * gpgga_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9 #include <cstring>
10 #include <cstdlib>
11
12 int gpgga_parse(nmea_code* gga, gnss_info* info){
13 gnss_time utc;
14 gnss_satinfo sati;
15 memset((void*)&sati,0,sizeof(gnss_satinfo));
16 char *str = gga->get_parameter(1);
17 char h[3]{'\0'}; strncpy(h,str,2);
18 char m[3]{'\0'}; strncpy(m,str+2,2);
19 char s[3]{'\0'}; strncpy(s,str+4,2);
20 char hs[4]{'\0'};strncpy(hs,str+7,3);
21 char dir;
22 gnss_pos coords;
23
24 utc.hour = atoi(h);
25 utc.min = atoi(m);
26 utc.sec = atoi(s);
27 utc.hsec = atoi(hs);
28
29 info->set_utc(&utc,NMEA_TIME);
30
31 dir = gga->get_parameter(3)[0];
32 str = gga->get_parameter(2); coords.lat = (dir == 'N')?atof(str):-1*atof(str);
33 dir = gga->get_parameter(5)[0];
34 str = gga->get_parameter(4); coords.lon = (dir == 'E')?atof(str):-1*atof(str);
35 info->set_pos(&coords);
36
37 str = gga->get_parameter(6); info->set_sig(atoi(str));
38 str = gga->get_parameter(7); sati.inview = atoi(str);
39 str = gga->get_parameter(8); info->set_hdop(atof(str));
40 str = gga->get_parameter(9); info->set_elv(atof(str));
41
42 info->set_smask(GPGGA);
43 return 1;
44 }
@@ -0,0 +1,12
1 /*
2 * gpgll_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int gpgll_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * gpgsa_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int gpgsa_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * gpgsv_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int gpgsv_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * gprmc_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int gprmc_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * gpvtg_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int gpvtg_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,39
1 /*
2 * nmea_defs.cpp
3 *
4 * Created on: Oct 30, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9 #include <map>
10 #include <string>
11
12
13 void subscribe_nmea_codes(code& supported_codes){
14 // standard NMEA codes
15 supported_codes["GPALM"] = &gpalm_parse;
16 // GARMIN's NMEA codes
17 supported_codes["PGRMI"] = &pgrmi_parse;
18 supported_codes["PGRMC"] = &pgrmc_parse;
19 supported_codes["PGRMC1"] = &pgrmc1_parse;
20 supported_codes["PGRMO"] = &pgrmo_parse;
21
22 /**
23 * receptor transmite estos codigos
24 */
25 // standard NMEA codes
26 supported_codes["GPGGA"] = &gpgga_parse;
27 supported_codes["GPGSA"] = &gpgsa_parse;
28 supported_codes["GPGSV"] = &gpgsv_parse;
29 supported_codes["GPRMC"] = &gprmc_parse;
30 supported_codes["GPVTG"] = &gpvtg_parse;
31 supported_codes["GPGLL"] = &gpgll_parse;
32 // GARMIN's NMEA codes
33 supported_codes["PGRME"] = &pgrme_parse;
34 supported_codes["PGRMF"] = &pgrmf_parse;
35 supported_codes["PGRMM"] = &pgrmm_parse;
36 supported_codes["PGRMT"] = &pgrmt_parse;
37 supported_codes["PGRMV"] = &pgrmv_parse;
38 supported_codes["PGRMB"] = &pgrmb_parse;
39 }
@@ -0,0 +1,58
1 /*
2 * nmea_defs.h
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #pragma once
9
10 #ifndef PARSE_NMEA_DEFS_H_
11 #define PARSE_NMEA_DEFS_H_
12
13 #include "../nmea_code.h"
14 #include "../gnss_info.h"
15 #include <map>
16 #include <string>
17
18 #define GPNON 0x0000 /**< Unknown packet type. */
19 #define GPGGA 0x0001 /**< GGA - Essential fix data which provide 3D location and accuracy data. */
20 #define GPGSA 0x0002 /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
21 #define GPGSV 0x0004 /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
22 #define GPRMC 0x0008 /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
23 #define GPVTG 0x0010 /**< VTG - Actual track made good and speed over ground. */
24 #define GPALM 0x0020
25 #define GPGLL 0x0040
26 #define PGRMI 0x0080
27 #define PGRMC 0x0100
28 #define PGRMC1 0x0200
29 #define PGRMO 0x0400
30
31 typedef int (*pnmea_parse)(nmea_code*, gnss_info*);
32 typedef std::map<std::string, pnmea_parse> code;
33
34
35 int gpalm_parse(nmea_code*, gnss_info*);
36 int pgrmi_parse(nmea_code*, gnss_info*);
37 int pgrmc_parse(nmea_code*, gnss_info*);
38 int pgrmc1_parse(nmea_code*, gnss_info*);
39 int pgrmo_parse(nmea_code*, gnss_info*);
40
41 int gpgga_parse(nmea_code*, gnss_info*);
42 int gpgsa_parse(nmea_code*, gnss_info*);
43 int gpgsv_parse(nmea_code*, gnss_info*);
44 int gprmc_parse(nmea_code*, gnss_info*);
45 int gpvtg_parse(nmea_code*, gnss_info*);
46 int gpgll_parse(nmea_code*, gnss_info*);
47 int pgrme_parse(nmea_code*, gnss_info*);
48 int pgrmf_parse(nmea_code*, gnss_info*);
49 int pgrmm_parse(nmea_code*, gnss_info*);
50 int pgrmt_parse(nmea_code*, gnss_info*);
51 int pgrmv_parse(nmea_code*, gnss_info*);
52 int pgrmb_parse(nmea_code*, gnss_info*);
53
54
55
56 void subscribe_nmea_codes(code&);
57
58 #endif /* PARSE_NMEA_DEFS_H_ */
@@ -0,0 +1,12
1 /*
2 * pgrmb_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmb_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmc1_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmc1_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmc_parce.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmc_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrme_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrme_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmf_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmf_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmi_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmi_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmm_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmm_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmo_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmo_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmt_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmt_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,12
1 /*
2 * pgrmv_parse.cpp
3 *
4 * Created on: Oct 29, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "nmea_defs.h"
9
10 int pgrmv_parse(nmea_code*, gnss_info*){
11 return 0;
12 }
@@ -0,0 +1,18
1 /*
2 * rtcctrl.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "rtcctrl.h"
9
10 rtc_ctrl::rtc_ctrl():
11 rtc_config(nullptr){
12 // TODO Auto-generated constructor stub
13
14 }
15
16 rtc_ctrl::~rtc_ctrl() {
17 // TODO Auto-generated destructor stub
18 }
@@ -0,0 +1,27
1 /*
2 * rtcctrl.h
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef TIMEENGINE_RTCCTRL_H_
9 #define TIMEENGINE_RTCCTRL_H_
10
11 #include "../utils/defs.h"
12
13 class rtc_ctrl {
14 public:
15 rtc_ctrl();
16 virtual ~rtc_ctrl();
17
18 bool rtcCtrl_configure(void*);
19 bool rtcCtrl_set_time(void*);
20 bool rtcCtrl_get_time(void*);
21 bool rtcCtrl_activate_pps(void*);
22
23 private:
24 rtc_config_struct* rtc_config;
25 };
26
27 #endif /* TIMEENGINE_RTCCTRL_H_ */
@@ -0,0 +1,20
1 /*
2 * timeEnginectrl.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "timeEnginectrl.h"
9
10 timeEngine_ctrl::timeEngine_ctrl():
11 te_status(nullptr),te_tmpkg(nullptr),
12 te_command(nullptr){
13 // TODO Auto-generated constructor stub
14
15 }
16
17 timeEngine_ctrl::~timeEngine_ctrl() {
18 // TODO Auto-generated destructor stub
19 }
20
@@ -0,0 +1,37
1 /*
2 * timeEnginectrl.h
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef TIMEENGINE_TIMEENGINECTRL_H_
9 #define TIMEENGINE_TIMEENGINECTRL_H_
10
11 #include "../utils/defs.h"
12 #include "gnssctrl.h"
13 #include "clockctrl.h"
14 #include "rtcctrl.h"
15
16 class timeEngine_ctrl {
17 public:
18 timeEngine_ctrl();
19 virtual ~timeEngine_ctrl();
20
21 bool teCtrl_reset(void*);
22 bool teCtrl_get_status(void*);
23 bool teCtrl_get_position(void*);
24 bool teCtrl_send_command(void*);
25 bool teCtrl_activate_lock(void*);//solo para test
26 bool teCtrl_deactivate_lock(void*);//solo para test
27
28 private:
29 te_status_struct* te_status;
30 te_time_pkg* te_tmpkg;
31 te_command_struct* te_command;
32 gnss_ctrl te_gnss;
33 clock_ctrl te_clock;
34 rtc_ctrl te_rtc;
35 };
36
37 #endif /* TIMEENGINE_TIMEENGINECTRL_H_ */
@@ -0,0 +1,19
1 /*
2 * structs_defs.h
3 *
4 * Created on: Oct 15, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef STRUCTS_DEFS_H_
9 #define STRUCTS_DEFS_H_
10
11 #include "pe_defs.h"
12 #include "saig_defs.h"
13 #include "te_structs.h"
14
15 #define GNSSPOWER_ON 1
16 #define GNSSPOWER_OFF 2
17
18
19 #endif /* STRUCTS_DEFS_H_ */
@@ -0,0 +1,21
1 /*
2 * pe_defs.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef UTILS_PE_DEFS_H_
9 #define UTILS_PE_DEFS_H_
10
11 /**
12 *
13 */
14 typedef struct pe_data_pkg_{
15
16 }pe_data_pkg;
17
18
19
20
21 #endif /* UTILS_PE_DEFS_H_ */
@@ -0,0 +1,29
1 /*
2 * saig_defs.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef UTILS_SAIG_DEFS_H_
9 #define UTILS_SAIG_DEFS_H_
10
11 /**
12 *
13 */
14 typedef struct saig_data_pkg_{
15
16 }saig_data_pkg;
17
18
19 /**
20 *
21 */
22 typedef struct msPkr_params_{
23
24 }msPkr_params;
25
26
27
28
29 #endif /* UTILS_SAIG_DEFS_H_ */
@@ -0,0 +1,276
1 # Blank lines are permitted in this file.
2 # spread.conf sample file
3 #
4 # questions to spread@spread.org
5 #
6
7 #MINIMAL REQUIRED FILE
8 #
9 # Spread should work fine on one machine with just the uncommented
10 # lines below. The rest of the file documents all the options and
11 # more complex network setups.
12 #
13 # This configures one spread daemon running on port 4803 on localhost.
14
15 Spread_Segment 127.0.0.255:4803 {
16
17 localhost 127.0.0.1
18 }
19
20
21
22
23 # Spread options
24 #---------------------------------------------------------------------------
25 #---------------------------------------------------------------------------
26 #Set what internal Spread events are logged to the screen or file
27 # (see EventLogFile).
28 # Default setting is to enable PRINT and EXIT events only.
29 #The PRINT and EXIT types should always be enabled. The names of others are:
30 # EXIT PRINT DEBUG DATA_LINK NETWORK PROTOCOL SESSION
31 # CONFIGURATION MEMBERSHIP FLOW_CONTROL STATUS EVENTS
32 # GROUPS MEMORY SKIPLIST ALL NONE
33 # ALL and NONE are special and represent either enabling every type
34 # or enabling none of them.
35 # You can also use a "!" sign to negate a type,
36 # so { ALL !DATA_LINK } means log all events except data_link ones.
37
38 #DebugFlags = { PRINT EXIT }
39
40 # Set priority level of events to output to log file or screen
41 # The possible levels are:
42 # pDEBUG INFO WARNING ERROR CRITICAL FATAL
43 # Once selected all events tagged with that priority or higher will
44 # be output. FATAL events are always output and cause the daemon to
45 # shut down. Some Events are tagged with a priority of PRINT which
46 # causes them to print out no matter what priority level is set.
47 #
48 # The default level used if nothing is set is INFO.
49
50 #EventPriority = INFO
51
52 #Set whether to log to a file as opposed to stdout/stderr and what
53 # file to log to.
54 # Default is to log to stdout.
55 #
56 #If option is not set then logging is to stdout.
57 #If option is set then logging is to the filename specified.
58 # The filename can include a %h or %H escape that will be replaced at runtime
59 # by the hostname of the machine upon which the daemon is running.
60 # For example "EventLogFile = spreadlog_%h.log" with 2 machines
61 # running Spread (machine1.mydomain.com and machine2.mydomain.com) will
62 # cause the daemons to log to "spreadlog_machine1.mydomain.com.log" and
63 # "spreadlog_machine2.mydomain.com.log" respectively.
64
65 #EventLogFile = testlog.out
66
67 #Set whether to add a timestamp in front of all logged events or not.
68 # Default is no timestamps. Default format is "[%a %d %b %Y %H:%M:%S]".
69 #If option is commented out then no timestamp is added.
70 #If option is enabled then a timestamp is added with the default format
71 #If option is enabled and set equal to a string, then that string is used
72 # as the format string for the timestamp. The string must be a valid time
73 # format string as used by the strftime() function.
74
75 #EventTimeStamp
76 # or
77 #EventTimeStamp = "[%a %d %b %Y %H:%M:%S]"
78
79 #Set whether to add a precise (microsecond) resolution timestamp to all logged
80 # events or not. This option requires that EventTimeStamp is also enabled.
81 # If the option is commented out then the microsecond timestamp is not added
82 # If the option is uncommented then a microsecond time will print in addition
83 # to the H:M:S resolution timestamp provided by EventTimeStamp.
84
85 #EventPreciseTimeStamp
86
87 # Set to initialize daemon sequence numbers to a 'large' number for testing
88 # this is purely a debugging capability and should never be enabled on
89 # production systems (note one side effect of enabling this is that
90 # your system will experience an extra daemon membership every few messages
91 # so you REALLY do not want this turned on)
92 # If you want to change the initial value the sequence number is set to
93 # you need to edit the #define INITIAL_SEQUENCE_NEAR_WRAP at the top
94 # of configuration.h
95
96 #DebugInitialSequence
97
98 #Set whether to allow dangerous monitor commands
99 # like "partition, flow_control, or kill"
100 # Default setting is FALSE.
101 #If option is set to false then only "safe" monitor commands are allowed
102 # (such as requesting a status update).
103 #If option is set to true then all monitor commands are enabled.
104 # THIS IS A SECURTIY RISK IF YOUR NETWORK IS NOT PROTECTED!
105
106 DangerousMonitor = false
107
108 #Set handling of SO_REUSEADDR socket option for the daemon's TCP
109 # listener. This is useful for facilitating quick daemon restarts (OSes
110 # often hold onto the interface/port combination for a short period of time
111 # after daemon shut down).
112 #
113 # AUTO - Active when bound to specific interfaces (default).
114 # ON - Always active, regardless of interface.
115 # SECURITY RISK FOR ANY OS WHICH ALLOW DOUBLE BINDS BY DIFFERENT USERS
116 # OFF - Always off.
117
118 #SocketPortReuse = AUTO
119
120 #Set what the maximum per-session queue should be for messages before disconnecting
121 # a session. Spread will buffer upto that number of messages that are destined to the
122 # session, but that can not be delivered currently because the session is not reading fast enough.
123 # The compiled in default is usually 1000 if you havn't changed it in the spread_params.h file.
124
125 #MaxSessionMessages = 5000
126
127 #Sets the runtime directory used when the Spread daemon is run as root
128 # as the directory to chroot to. Defaults to the value of the
129 # compile-time preprocessor define SP_RUNTIME_DIR, which is generally
130 # "/var/run/spread".
131
132 #RuntimeDir = /var/run/spread
133
134 #Sets the unix user that the Spread daemon runs as (when launched as
135 # the "root" user). Not effective on a Windows system. Defaults to
136 # the user and group "spread".
137
138 #DaemonUser = spread
139 #DaemonGroup = spread
140
141
142 #Set the list of authentication methods that the daemon will allow
143 # and those which are required in all cases.
144 # All of the methods listed in "RequiredAuthMethods" will be checked,
145 # irregardless of what methods the client chooses.
146 # Of the methods listed is "AllowedAuthMethods" the client is
147 # permitted to choose one or more, and all the ones the client chooses
148 # will also be checked.
149 #
150 # To support older clients, if NULL is enabled, then older clients can
151 # connect without any authentication. Any methods which do not require
152 # any interaction with the client (such as IP) can also be enabled
153 # for older clients. If you enable methods that require interaction,
154 # then essentially all older clients will be locked out.
155 #
156 #The current choices are:
157 # NULL for default, allow anyone authentication
158 # IP for IP based checks using the spread.access_ip file
159
160 #RequiredAuthMethods = " "
161 #AllowedAuthMethods = "NULL"
162
163 #Set the current access control policy.
164 # This is only needed if you want to establish a customized policy.
165 # The default policy is to allow any actions by authenticated clients.
166 #AccessControlPolicy = "PERMIT"
167
168
169 # network description line.
170 # Spread_Segment <multicast address for subnet> <port> {
171 # port is optional, if not specified the default 4803 port is used.
172
173 #Spread_Segment 127.0.0.255:4803 {
174
175 # either a name or IP address. If both are given, than the name is taken
176 # as-is, and the IP address is used for that name.
177
178 # localhost 127.0.0.1
179 #}
180 # repeat for next sub-network
181
182 #Spread_Segment x.2.2.255 {
183
184 # other1 128.2.2.10
185 # 128.2.2.11
186 # other3.my.com
187 #}
188 # Spread will feel free to use broadcast messages within a sub-network.
189 # if you do not want this to happen, you should specify your machines on
190 # different logical sub-networks.
191
192 # IP-Multicast addresses can also be used as the multicast address for
193 # the logical sub-network as in this example. If IP-multicast is supported
194 # by the operating system, then the messages will only be received
195 # by those machines who are in the group and not by all others in the same
196 # sub-network as happens with broadcast addresses
197
198 #Spread_Segment 225.0.1.1:3333 {
199 # mcast1 1.2.3.4
200 # mcast2 1.2.3.6
201 #}
202
203 # Multi-homed host setup
204 #
205 # If you run Spread on hosts with multiple interfaces you may want to
206 # control which interfaces Spread uses for client connections and for
207 # the daemon-to-daemon (and monitor control) messages. This can be done
208 # by adding an extra stanza to each configured machine.
209 #
210 #Sample:
211 #
212 #Spread_Segment 225.0.1.1 {
213 # multihomed1 1.2.3.4 {
214 # D 192.168.0.4
215 # C 1.2.3.4 }
216 # multihomed2 1.2.3.5 {
217 # D 192.168.0.5
218 # C 1.2.3.5
219 # C 127.0.0.1 }
220 # multihomed3 1.2.3.6 {
221 # 192.168.0.6
222 # 1.2.3.6 }
223 #}
224 # This configuration sets up three multihomed machines into a Spread segment.
225 # The first host has a 'main' IP address of 1.2.3.4 and listens for client
226 # connections only on that interface. All daemon-to-daemon UDP multicasts and
227 # the tokens and any monitor messages must use the 192.168.0.4 interface.
228 # The second host multihomed2 has a similar setup, except it also listens for
229 # client connections on the localhost interface as well as the 1.2.3.5 interface.
230 # If you make any use of the extra interface stanza ( a { } block ) then you must
231 # explicitly configure ALL interfaces you want as Spread removes all defaults when
232 # you use the explicit notation.
233 # The third multihomed3 host uses a shorthand form of omitting the D or C option and
234 # just listening for all types of traffic and events on both the 192.168.0 and 1.2.3
235 # networks. If no letter is listed before the interface address then ALL types of
236 # events are handled on that interface.
237
238 # AcceleratedRing indicates which protocol to use. If false, then the regular Spread
239 # ring protocol is used. If true, then the accelerated ring protocol is used. If left
240 # unspecified, then Spread tries to guess if you are running on a WAN or LAN and uses
241 # the more appropriate protocol: the regular protocol on WANs and the accelerated protocol
242 # on LANs. Spread uses the heuristic that if all your daemon addresses are within the
243 # same /16 network then it assumes it is a LAN, otherwise it is a WAN. This same heurstic
244 # is used to pick the default timeouts (WAN or LAN) for the protocols too.
245 #
246 # Note that daemons can only talk with daemons that run the same protocol - they
247 # will refuse to talk with daemons that run the other protocol. The accelerated ring
248 # protocol uses a flow control algorithm similar to the normal protocol, with the
249 # exception that the token is sent before up to AcceleratedWindow packets of the
250 # PersonalWindow (the token still reflects these packets). In general, the closer
251 # AcceleratedWindow is to PersonalWindow the more acceleration can be expected -- up to
252 # a point. In our testing on 1Gb/s and 10Gb/s networks, raising AcceleratedWindow
253 # above 20 had significant negative side effects and actually lowered throughput.
254 #
255 #AcceleratedRing = true
256
257 # Flow Control Parameters
258 #
259 #Window = 160
260 #PersonalWindow = 20
261 #AcceleratedWindow = 15
262
263 # Membership Timeouts (in terms of milliseconds)
264 #
265 # If you specify any of these timeouts then you must specify all of them
266 # (and ensure that they make sense collectively)
267 #
268 #TokenTimeout = 1250
269 #HurryTimeout = 500
270 #AliveTimeout = 250
271 #JoinTimeout = 250
272 #RepTimeout = 625
273 #SegTimeout = 500
274 #GatherTimeout = 1250
275 #FormTimeout = 1250
276 #LookupTimeout = 30000
@@ -0,0 +1,135
1 /*
2 * te_defs.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef UTILS_TE_STRUCTS_H_
9 #define UTILS_TE_STRUCTS_H_
10
11 #include <inttypes.h>
12 #include <stdint.h>
13
14 ///////////////////////////////////////////////////////////////////////////////
15 // ESTRUCTURAS PARA MODULO DE CONTROL DE RECEPTOR GNSS (GPS-15xL)
16 ///////////////////////////////////////////////////////////////////////////////
17
18 /*!
19 *
20 */
21 typedef struct gnss_config_struct_{
22
23 }gnss_config_struct;
24
25 /*!
26 * \struct gnss_precise_time
27 * \brief Estructura de tiempo de GNSS para almacenar tiempo preciso.
28 * Almacena tiempo con resolucion de microsegundos.
29 */
30 typedef struct gnss_precise_time_{
31 int year; /*!< Ahno de la data adquirida */
32 int doy; /*!< Dia del ahno de la data adqirida */
33 int hour; /*!< Hora de la data adquirida */
34 int minu; /*!< Minutos de la data adquirida */
35 int sec; /*!< Segundos de la data adquirida */
36 int usec; /*!< Microsegndos de la data adquirida */
37 gnss_precise_time_(): year(0), doy(0), hour(0), minu(0), sec(0), usec(0){}
38 }gnss_precise_time;
39
40 ///////////////////////////////////////////////////////////////////////////////
41 // ESTRUCTURAS PARA EL MODULO DE CONTROL DEL GENERADOR DE CLOCK
42 ///////////////////////////////////////////////////////////////////////////////
43
44 /*!
45 *
46 */
47 typedef struct clock_config_struct_{
48
49 }clock_config_struct;
50
51 /*!
52 *
53 */
54 typedef struct clock_state_struct_{
55
56 }clock_state_struct;
57
58 ///////////////////////////////////////////////////////////////////////////////
59 // ESTRUCTURAS PARA MODULO DE CONTROL DE RTC
60 ///////////////////////////////////////////////////////////////////////////////
61
62 /*!
63 * \struct ds1308_ctl_byte
64 * \brief Estructura para almacenar informacion de configuracion para
65 * el registro con direccion DS1308_CTL_ADD (0x07) del DS1308.
66 */
67 typedef struct ds1308_ctl_byte_ {
68 uint8_t rs0:1;
69 uint8_t rs1:1;
70 uint8_t bbclk:1;
71 uint8_t los:1;
72 uint8_t sqwe:1;
73 uint8_t osf:1;
74 uint8_t eclk:1;
75 uint8_t out:1;
76 ds1308_ctl_byte_(): rs0(0), rs1(0), bbclk(0), los(0), sqwe(0),
77 osf(0), eclk(1), out(0){}
78 }ds1308_ctl_byte;
79
80 /*!
81 * \struct ds1308_clock_halt
82 * \brief Estructura para configurar el arranque o parada de funciones
83 * timekeeping del DS1308
84 */
85 typedef struct ds1308_clock_halt_ {
86 uint8_t dummy_dont_use:7;
87 uint8_t ch:1;
88 ds1308_clock_halt_(): dummy_dont_use(0), ch(0){}
89 }ds1308_clock_halt;
90
91 /*!
92 * \struct rtc_config_struct
93 * \brief Almacena toda la informmacion necesaria para configurar el IC
94 * DS1308.
95 */
96 typedef struct rtc_config_struct_{
97 ds1308_clock_halt clk_halt;
98 ds1308_ctl_byte ctl_byte;
99 }rtc_config_struct;
100
101 ///////////////////////////////////////////////////////////////////////////////
102 //
103 ///////////////////////////////////////////////////////////////////////////////
104
105 /*!
106 *
107 */
108 typedef struct te_status_struct_{
109
110 }te_status_struct;
111
112 /*!
113 *
114 */
115 typedef struct te_time_pkg_{
116 gnss_precise_time time; /*!< Tiempo de adquisicion de un PPS de GNSS
117 especifico */
118 uint16_t pps_serial; /*!< Numero serial de un PPS desde que la linea de
119 enganche GNSS (LOCK) fue activada (max 1800) */
120 bool is_gnss_time; /*!< true si el tiempo dado proviene del un
121 receptor GNSS */
122 gnss_precise_time * pnext; /*!< Apunta al siguiente paquete de tiempo */
123 gnss_precise_time * previous; /*!< Apunta al paquete de tempo anterior. */
124 te_time_pkg_(): pps_serial(0), is_gnss_time(false), pnext(0), previous(0){}
125 }te_time_pkg;
126
127 /*!
128 *
129 */
130 typedef struct te_command_struct_{
131
132 }te_command_struct;
133
134
135 #endif /* UTILS_TE_STRUCTS_H_ */
@@ -0,0 +1,108
1 /*
2 * uart.cpp
3 *
4 * Created on: Oct 16, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include "uart.h"
9
10 namespace rbp {
11
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <termios.h>
16
17 /*!
18 *
19 */
20 uart::uart(uint32_t baudrate,int buffsz){
21 fs=-1;
22 buffsize = buffsz;
23 rx_buffer = nullptr;
24 tx_buffer = nullptr;
25 if(!setup(baudrate)){
26 delete this; //TODO log
27 }
28 }
29
30 /*!
31 *
32 */
33 uart::~uart() {
34 if(fs!=-1){
35 close(fs);
36 }
37 }
38
39
40 /*!
41 *
42 */
43 bool uart::setup(uint32_t baudrate){
44 fs = -1;
45 //Open in non blocking read/write mode
46 fs = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
47 if (fs == -1)
48 {
49 printf("Error - Unable to open UART. Ensure it is not in use by another application\n");// TODO cambiar al sistema de log
50 return false;
51 }
52 struct termios options;
53 tcgetattr(fs, &options);
54 options.c_cflag = baudrate | CS8 | CLOCAL | CREAD;
55 options.c_iflag = IGNPAR;
56 options.c_oflag = 0;
57 options.c_lflag = 0;
58 tcflush(fs, TCIFLUSH);
59 tcsetattr(fs, TCSANOW, &options);
60 return true;
61 }
62
63 /*!
64 *
65 */
66 ssize_t uart::receive(uint8_t* rx_buff){
67 ssize_t cnt=0;
68 if (fs != -1)
69 {
70 rx_buffer = new uint8_t[256];
71 cnt = read(fs, (void*)rx_buffer, 255);
72 if (cnt < 0)
73 {
74 //An error occured (will occur if there are no bytes)
75 //TODO cambiar a sistema de log
76 }
77 else if (cnt == 0)
78 {
79 //No data waiting
80 //TODO cambiar a sistema de log
81 }
82 else
83 {
84 rx_buffer[cnt] = '\0';
85 rx_buff = rx_buffer;
86 }
87 }
88 return cnt;
89 }
90
91 /*!
92 *
93 */
94 ssize_t uart::transmit(uint8_t* tx_buff, size_t nbytes){
95 ssize_t cnt=0;
96 if (fs != -1)
97 {
98 tx_buffer = tx_buff;
99 cnt = write(fs, (void*)tx_buffer, nbytes); //Filestream, bytes to write, number of bytes to write
100 if (cnt < 0)
101 {
102 printf("UART TX error\n");//TODO cambiar a sistema de log
103 }
104 }
105 return cnt;
106 }
107
108 } /* namespace rbp */
@@ -0,0 +1,38
1 /*
2 * uart.h
3 * code based on:
4 * http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart
5 * Created on: Oct 16, 2014
6 * Author: Alan Aguilar Sologuren
7 */
8
9 #ifndef UTILS_UART_H_
10 #define UTILS_UART_H_
11
12 #include <unistd.h>
13 #include <stdint.h>
14
15 namespace rbp {
16
17 class uart {
18 public:
19 uart(uint32_t, int);
20 virtual ~uart();
21
22 ssize_t receive(uint8_t*);
23 ssize_t transmit(uint8_t*, size_t);
24
25 private:
26
27 int fs;
28 uint8_t *rx_buffer;
29 uint8_t *tx_buffer;
30 size_t buffsize;
31
32 bool setup(uint32_t);
33
34 };
35
36 } /* namespace rbp */
37
38 #endif /* UTILS_UART_H_ */
@@ -0,0 +1,237
1 /*
2 Arduino.h - Main include file for the Arduino SDK
3 Copyright (c) 2005-2013 Arduino Team. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef Arduino_h
21 #define Arduino_h
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26
27 #include <avr/pgmspace.h>
28 #include <avr/io.h>
29 #include <avr/interrupt.h>
30
31 #include "binary.h"
32
33 #ifdef __cplusplus
34 extern "C"{
35 #endif
36
37 #define HIGH 0x1
38 #define LOW 0x0
39
40 #define INPUT 0x0
41 #define OUTPUT 0x1
42 #define INPUT_PULLUP 0x2
43
44 #define true 0x1
45 #define false 0x0
46
47 #define PI 3.1415926535897932384626433832795
48 #define HALF_PI 1.5707963267948966192313216916398
49 #define TWO_PI 6.283185307179586476925286766559
50 #define DEG_TO_RAD 0.017453292519943295769236907684886
51 #define RAD_TO_DEG 57.295779513082320876798154814105
52
53 #define SERIAL 0x0
54 #define DISPLAY 0x1
55
56 #define LSBFIRST 0
57 #define MSBFIRST 1
58
59 #define CHANGE 1
60 #define FALLING 2
61 #define RISING 3
62
63 #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
64 #define DEFAULT 0
65 #define EXTERNAL 1
66 #define INTERNAL 2
67 #else
68 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
69 #define INTERNAL1V1 2
70 #define INTERNAL2V56 3
71 #else
72 #define INTERNAL 3
73 #endif
74 #define DEFAULT 1
75 #define EXTERNAL 0
76 #endif
77
78 // undefine stdlib's abs if encountered
79 #ifdef abs
80 #undef abs
81 #endif
82
83 #define min(a,b) ((a)<(b)?(a):(b))
84 #define max(a,b) ((a)>(b)?(a):(b))
85 #define abs(x) ((x)>0?(x):-(x))
86 #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
87 #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
88 #define radians(deg) ((deg)*DEG_TO_RAD)
89 #define degrees(rad) ((rad)*RAD_TO_DEG)
90 #define sq(x) ((x)*(x))
91
92 #define interrupts() sei()
93 #define noInterrupts() cli()
94
95 #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
96 #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
97 #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
98
99 #define lowByte(w) ((uint8_t) ((w) & 0xff))
100 #define highByte(w) ((uint8_t) ((w) >> 8))
101
102 #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
103 #define bitSet(value, bit) ((value) |= (1UL << (bit)))
104 #define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
105 #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
106
107
108 typedef unsigned int word;
109
110 #define bit(b) (1UL << (b))
111
112 typedef uint8_t boolean;
113 typedef uint8_t byte;
114
115 void init(void);
116 void initVariant(void);
117
118 int atexit(void (*func)()) __attribute__((weak));
119
120 void pinMode(uint8_t, uint8_t);
121 void digitalWrite(uint8_t, uint8_t);
122 int digitalRead(uint8_t);
123 int analogRead(uint8_t);
124 void analogReference(uint8_t mode);
125 void analogWrite(uint8_t, int);
126
127 unsigned long millis(void);
128 unsigned long micros(void);
129 void delay(unsigned long);
130 void delayMicroseconds(unsigned int us);
131 unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
132
133 void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
134 uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
135
136 void attachInterrupt(uint8_t, void (*)(void), int mode);
137 void detachInterrupt(uint8_t);
138
139 void setup(void);
140 void loop(void);
141
142 // Get the bit location within the hardware port of the given virtual pin.
143 // This comes from the pins_*.c file for the active board configuration.
144
145 #define analogInPinToBit(P) (P)
146
147 // On the ATmega1280, the addresses of some of the port registers are
148 // greater than 255, so we can't store them in uint8_t's.
149 extern const uint16_t PROGMEM port_to_mode_PGM[];
150 extern const uint16_t PROGMEM port_to_input_PGM[];
151 extern const uint16_t PROGMEM port_to_output_PGM[];
152
153 extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
154 // extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
155 extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
156 extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
157
158 // Get the bit location within the hardware port of the given virtual pin.
159 // This comes from the pins_*.c file for the active board configuration.
160 //
161 // These perform slightly better as macros compared to inline functions
162 //
163 #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
164 #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
165 #define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
166 #define analogInPinToBit(P) (P)
167 #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
168 #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
169 #define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
170
171 #define NOT_A_PIN 0
172 #define NOT_A_PORT 0
173
174 #ifdef ARDUINO_MAIN
175 #define PA 1
176 #define PB 2
177 #define PC 3
178 #define PD 4
179 #define PE 5
180 #define PF 6
181 #define PG 7
182 #define PH 8
183 #define PJ 10
184 #define PK 11
185 #define PL 12
186 #endif
187
188 #define NOT_ON_TIMER 0
189 #define TIMER0A 1
190 #define TIMER0B 2
191 #define TIMER1A 3
192 #define TIMER1B 4
193 #define TIMER2 5
194 #define TIMER2A 6
195 #define TIMER2B 7
196
197 #define TIMER3A 8
198 #define TIMER3B 9
199 #define TIMER3C 10
200 #define TIMER4A 11
201 #define TIMER4B 12
202 #define TIMER4C 13
203 #define TIMER4D 14
204 #define TIMER5A 15
205 #define TIMER5B 16
206 #define TIMER5C 17
207
208 #ifdef __cplusplus
209 } // extern "C"
210 #endif
211
212 #ifdef __cplusplus
213 #include "WCharacter.h"
214 #include "WString.h"
215 #include "HardwareSerial.h"
216
217 uint16_t makeWord(uint16_t w);
218 uint16_t makeWord(byte h, byte l);
219
220 #define word(...) makeWord(__VA_ARGS__)
221
222 unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
223
224 void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
225 void noTone(uint8_t _pin);
226
227 // WMath prototypes
228 long random(long);
229 long random(long, long);
230 void randomSeed(unsigned int);
231 long map(long, long, long, long, long);
232
233 #endif
234
235 #include "pins_arduino.h"
236
237 #endif
@@ -0,0 +1,208
1
2
3 /* Copyright (c) 2011, Peter Barrett
4 **
5 ** Permission to use, copy, modify, and/or distribute this software for
6 ** any purpose with or without fee is hereby granted, provided that the
7 ** above copyright notice and this permission notice appear in all copies.
8 **
9 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
12 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
13 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
14 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 ** SOFTWARE.
17 */
18
19 #include "Platform.h"
20 #include "USBAPI.h"
21 #include <avr/wdt.h>
22
23 #if defined(USBCON)
24 #ifdef CDC_ENABLED
25
26 typedef struct
27 {
28 u32 dwDTERate;
29 u8 bCharFormat;
30 u8 bParityType;
31 u8 bDataBits;
32 u8 lineState;
33 } LineInfo;
34
35 static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
36
37 #define WEAK __attribute__ ((weak))
38
39 extern const CDCDescriptor _cdcInterface PROGMEM;
40 const CDCDescriptor _cdcInterface =
41 {
42 D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
43
44 // CDC communication interface
45 D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
46 D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
47 D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
48 D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
49 D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
50 D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
51
52 // CDC data interface
53 D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
54 D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0),
55 D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
56 };
57
58 int WEAK CDC_GetInterface(u8* interfaceNum)
59 {
60 interfaceNum[0] += 2; // uses 2
61 return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
62 }
63
64 bool WEAK CDC_Setup(Setup& setup)
65 {
66 u8 r = setup.bRequest;
67 u8 requestType = setup.bmRequestType;
68
69 if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
70 {
71 if (CDC_GET_LINE_CODING == r)
72 {
73 USB_SendControl(0,(void*)&_usbLineInfo,7);
74 return true;
75 }
76 }
77
78 if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
79 {
80 if (CDC_SET_LINE_CODING == r)
81 {
82 USB_RecvControl((void*)&_usbLineInfo,7);
83 return true;
84 }
85
86 if (CDC_SET_CONTROL_LINE_STATE == r)
87 {
88 _usbLineInfo.lineState = setup.wValueL;
89
90 // auto-reset into the bootloader is triggered when the port, already
91 // open at 1200 bps, is closed. this is the signal to start the watchdog
92 // with a relatively long period so it can finish housekeeping tasks
93 // like servicing endpoints before the sketch ends
94 if (1200 == _usbLineInfo.dwDTERate) {
95 // We check DTR state to determine if host port is open (bit 0 of lineState).
96 if ((_usbLineInfo.lineState & 0x01) == 0) {
97 *(uint16_t *)0x0800 = 0x7777;
98 wdt_enable(WDTO_120MS);
99 } else {
100 // Most OSs do some intermediate steps when configuring ports and DTR can
101 // twiggle more than once before stabilizing.
102 // To avoid spurious resets we set the watchdog to 250ms and eventually
103 // cancel if DTR goes back high.
104
105 wdt_disable();
106 wdt_reset();
107 *(uint16_t *)0x0800 = 0x0;
108 }
109 }
110 return true;
111 }
112 }
113 return false;
114 }
115
116
117 void Serial_::begin(unsigned long baud_count)
118 {
119 peek_buffer = -1;
120 }
121
122 void Serial_::begin(unsigned long baud_count, byte config)
123 {
124 peek_buffer = -1;
125 }
126
127 void Serial_::end(void)
128 {
129 }
130
131 int Serial_::available(void)
132 {
133 if (peek_buffer >= 0) {
134 return 1 + USB_Available(CDC_RX);
135 }
136 return USB_Available(CDC_RX);
137 }
138
139 int Serial_::peek(void)
140 {
141 if (peek_buffer < 0)
142 peek_buffer = USB_Recv(CDC_RX);
143 return peek_buffer;
144 }
145
146 int Serial_::read(void)
147 {
148 if (peek_buffer >= 0) {
149 int c = peek_buffer;
150 peek_buffer = -1;
151 return c;
152 }
153 return USB_Recv(CDC_RX);
154 }
155
156 void Serial_::flush(void)
157 {
158 USB_Flush(CDC_TX);
159 }
160
161 size_t Serial_::write(uint8_t c)
162 {
163 return write(&c, 1);
164 }
165
166 size_t Serial_::write(const uint8_t *buffer, size_t size)
167 {
168 /* only try to send bytes if the high-level CDC connection itself
169 is open (not just the pipe) - the OS should set lineState when the port
170 is opened and clear lineState when the port is closed.
171 bytes sent before the user opens the connection or after
172 the connection is closed are lost - just like with a UART. */
173
174 // TODO - ZE - check behavior on different OSes and test what happens if an
175 // open connection isn't broken cleanly (cable is yanked out, host dies
176 // or locks up, or host virtual serial port hangs)
177 if (_usbLineInfo.lineState > 0) {
178 int r = USB_Send(CDC_TX,buffer,size);
179 if (r > 0) {
180 return r;
181 } else {
182 setWriteError();
183 return 0;
184 }
185 }
186 setWriteError();
187 return 0;
188 }
189
190 // This operator is a convenient way for a sketch to check whether the
191 // port has actually been configured and opened by the host (as opposed
192 // to just being connected to the host). It can be used, for example, in
193 // setup() before printing to ensure that an application on the host is
194 // actually ready to receive and display the data.
195 // We add a short delay before returning to fix a bug observed by Federico
196 // where the port is configured (lineState != 0) but not quite opened.
197 Serial_::operator bool() {
198 bool result = false;
199 if (_usbLineInfo.lineState > 0)
200 result = true;
201 delay(10);
202 return result;
203 }
204
205 Serial_ Serial;
206
207 #endif
208 #endif /* if defined(USBCON) */
@@ -0,0 +1,45
1 /*
2 Client.h - Base class that provides Client
3 Copyright (c) 2011 Adrian McEwen. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef client_h
21 #define client_h
22 #include "Print.h"
23 #include "Stream.h"
24 #include "IPAddress.h"
25
26 class Client : public Stream {
27
28 public:
29 virtual int connect(IPAddress ip, uint16_t port) =0;
30 virtual int connect(const char *host, uint16_t port) =0;
31 virtual size_t write(uint8_t) =0;
32 virtual size_t write(const uint8_t *buf, size_t size) =0;
33 virtual int available() = 0;
34 virtual int read() = 0;
35 virtual int read(uint8_t *buf, size_t size) = 0;
36 virtual int peek() = 0;
37 virtual void flush() = 0;
38 virtual void stop() = 0;
39 virtual uint8_t connected() = 0;
40 virtual operator bool() = 0;
41 protected:
42 uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
43 };
44
45 #endif
This diff has been collapsed as it changes many lines, (520 lines changed) Show them Hide them
@@ -0,0 +1,520
1
2
3 /* Copyright (c) 2011, Peter Barrett
4 **
5 ** Permission to use, copy, modify, and/or distribute this software for
6 ** any purpose with or without fee is hereby granted, provided that the
7 ** above copyright notice and this permission notice appear in all copies.
8 **
9 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
12 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
13 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
14 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 ** SOFTWARE.
17 */
18
19 #include "Platform.h"
20 #include "USBAPI.h"
21 #include "USBDesc.h"
22
23 #if defined(USBCON)
24 #ifdef HID_ENABLED
25
26 //#define RAWHID_ENABLED
27
28 // Singletons for mouse and keyboard
29
30 Mouse_ Mouse;
31 Keyboard_ Keyboard;
32
33 //================================================================================
34 //================================================================================
35
36 // HID report descriptor
37
38 #define LSB(_x) ((_x) & 0xFF)
39 #define MSB(_x) ((_x) >> 8)
40
41 #define RAWHID_USAGE_PAGE 0xFFC0
42 #define RAWHID_USAGE 0x0C00
43 #define RAWHID_TX_SIZE 64
44 #define RAWHID_RX_SIZE 64
45
46 extern const u8 _hidReportDescriptor[] PROGMEM;
47 const u8 _hidReportDescriptor[] = {
48
49 // Mouse
50 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
51 0x09, 0x02, // USAGE (Mouse)
52 0xa1, 0x01, // COLLECTION (Application)
53 0x09, 0x01, // USAGE (Pointer)
54 0xa1, 0x00, // COLLECTION (Physical)
55 0x85, 0x01, // REPORT_ID (1)
56 0x05, 0x09, // USAGE_PAGE (Button)
57 0x19, 0x01, // USAGE_MINIMUM (Button 1)
58 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
59 0x15, 0x00, // LOGICAL_MINIMUM (0)
60 0x25, 0x01, // LOGICAL_MAXIMUM (1)
61 0x95, 0x03, // REPORT_COUNT (3)
62 0x75, 0x01, // REPORT_SIZE (1)
63 0x81, 0x02, // INPUT (Data,Var,Abs)
64 0x95, 0x01, // REPORT_COUNT (1)
65 0x75, 0x05, // REPORT_SIZE (5)
66 0x81, 0x03, // INPUT (Cnst,Var,Abs)
67 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
68 0x09, 0x30, // USAGE (X)
69 0x09, 0x31, // USAGE (Y)
70 0x09, 0x38, // USAGE (Wheel)
71 0x15, 0x81, // LOGICAL_MINIMUM (-127)
72 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
73 0x75, 0x08, // REPORT_SIZE (8)
74 0x95, 0x03, // REPORT_COUNT (3)
75 0x81, 0x06, // INPUT (Data,Var,Rel)
76 0xc0, // END_COLLECTION
77 0xc0, // END_COLLECTION
78
79 // Keyboard
80 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
81 0x09, 0x06, // USAGE (Keyboard)
82 0xa1, 0x01, // COLLECTION (Application)
83 0x85, 0x02, // REPORT_ID (2)
84 0x05, 0x07, // USAGE_PAGE (Keyboard)
85
86 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
87 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
88 0x15, 0x00, // LOGICAL_MINIMUM (0)
89 0x25, 0x01, // LOGICAL_MAXIMUM (1)
90 0x75, 0x01, // REPORT_SIZE (1)
91
92 0x95, 0x08, // REPORT_COUNT (8)
93 0x81, 0x02, // INPUT (Data,Var,Abs)
94 0x95, 0x01, // REPORT_COUNT (1)
95 0x75, 0x08, // REPORT_SIZE (8)
96 0x81, 0x03, // INPUT (Cnst,Var,Abs)
97
98 0x95, 0x06, // REPORT_COUNT (6)
99 0x75, 0x08, // REPORT_SIZE (8)
100 0x15, 0x00, // LOGICAL_MINIMUM (0)
101 0x25, 0x65, // LOGICAL_MAXIMUM (101)
102 0x05, 0x07, // USAGE_PAGE (Keyboard)
103
104 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
105 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
106 0x81, 0x00, // INPUT (Data,Ary,Abs)
107 0xc0, // END_COLLECTION
108
109 #ifdef RAWHID_ENABLED
110 // RAW HID
111 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
112 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
113
114 0xA1, 0x01, // Collection 0x01
115 0x85, 0x03, // REPORT_ID (3)
116 0x75, 0x08, // report size = 8 bits
117 0x15, 0x00, // logical minimum = 0
118 0x26, 0xFF, 0x00, // logical maximum = 255
119
120 0x95, 64, // report count TX
121 0x09, 0x01, // usage
122 0x81, 0x02, // Input (array)
123
124 0x95, 64, // report count RX
125 0x09, 0x02, // usage
126 0x91, 0x02, // Output (array)
127 0xC0 // end collection
128 #endif
129 };
130
131 extern const HIDDescriptor _hidInterface PROGMEM;
132 const HIDDescriptor _hidInterface =
133 {
134 D_INTERFACE(HID_INTERFACE,1,3,0,0),
135 D_HIDREPORT(sizeof(_hidReportDescriptor)),
136 D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
137 };
138
139 //================================================================================
140 //================================================================================
141 // Driver
142
143 u8 _hid_protocol = 1;
144 u8 _hid_idle = 1;
145
146 #define WEAK __attribute__ ((weak))
147
148 int WEAK HID_GetInterface(u8* interfaceNum)
149 {
150 interfaceNum[0] += 1; // uses 1
151 return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
152 }
153
154 int WEAK HID_GetDescriptor(int i)
155 {
156 return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
157 }
158
159 void WEAK HID_SendReport(u8 id, const void* data, int len)
160 {
161 USB_Send(HID_TX, &id, 1);
162 USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
163 }
164
165 bool WEAK HID_Setup(Setup& setup)
166 {
167 u8 r = setup.bRequest;
168 u8 requestType = setup.bmRequestType;
169 if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
170 {
171 if (HID_GET_REPORT == r)
172 {
173 //HID_GetReport();
174 return true;
175 }
176 if (HID_GET_PROTOCOL == r)
177 {
178 //Send8(_hid_protocol); // TODO
179 return true;
180 }
181 }
182
183 if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
184 {
185 if (HID_SET_PROTOCOL == r)
186 {
187 _hid_protocol = setup.wValueL;
188 return true;
189 }
190
191 if (HID_SET_IDLE == r)
192 {
193 _hid_idle = setup.wValueL;
194 return true;
195 }
196 }
197 return false;
198 }
199
200 //================================================================================
201 //================================================================================
202 // Mouse
203
204 Mouse_::Mouse_(void) : _buttons(0)
205 {
206 }
207
208 void Mouse_::begin(void)
209 {
210 }
211
212 void Mouse_::end(void)
213 {
214 }
215
216 void Mouse_::click(uint8_t b)
217 {
218 _buttons = b;
219 move(0,0,0);
220 _buttons = 0;
221 move(0,0,0);
222 }
223
224 void Mouse_::move(signed char x, signed char y, signed char wheel)
225 {
226 u8 m[4];
227 m[0] = _buttons;
228 m[1] = x;
229 m[2] = y;
230 m[3] = wheel;
231 HID_SendReport(1,m,4);
232 }
233
234 void Mouse_::buttons(uint8_t b)
235 {
236 if (b != _buttons)
237 {
238 _buttons = b;
239 move(0,0,0);
240 }
241 }
242
243 void Mouse_::press(uint8_t b)
244 {
245 buttons(_buttons | b);
246 }
247
248 void Mouse_::release(uint8_t b)
249 {
250 buttons(_buttons & ~b);
251 }
252
253 bool Mouse_::isPressed(uint8_t b)
254 {
255 if ((b & _buttons) > 0)
256 return true;
257 return false;
258 }
259
260 //================================================================================
261 //================================================================================
262 // Keyboard
263
264 Keyboard_::Keyboard_(void)
265 {
266 }
267
268 void Keyboard_::begin(void)
269 {
270 }
271
272 void Keyboard_::end(void)
273 {
274 }
275
276 void Keyboard_::sendReport(KeyReport* keys)
277 {
278 HID_SendReport(2,keys,sizeof(KeyReport));
279 }
280
281 extern
282 const uint8_t _asciimap[128] PROGMEM;
283
284 #define SHIFT 0x80
285 const uint8_t _asciimap[128] =
286 {
287 0x00, // NUL
288 0x00, // SOH
289 0x00, // STX
290 0x00, // ETX
291 0x00, // EOT
292 0x00, // ENQ
293 0x00, // ACK
294 0x00, // BEL
295 0x2a, // BS Backspace
296 0x2b, // TAB Tab
297 0x28, // LF Enter
298 0x00, // VT
299 0x00, // FF
300 0x00, // CR
301 0x00, // SO
302 0x00, // SI
303 0x00, // DEL
304 0x00, // DC1
305 0x00, // DC2
306 0x00, // DC3
307 0x00, // DC4
308 0x00, // NAK
309 0x00, // SYN
310 0x00, // ETB
311 0x00, // CAN
312 0x00, // EM
313 0x00, // SUB
314 0x00, // ESC
315 0x00, // FS
316 0x00, // GS
317 0x00, // RS
318 0x00, // US
319
320 0x2c, // ' '
321 0x1e|SHIFT, // !
322 0x34|SHIFT, // "
323 0x20|SHIFT, // #
324 0x21|SHIFT, // $
325 0x22|SHIFT, // %
326 0x24|SHIFT, // &
327 0x34, // '
328 0x26|SHIFT, // (
329 0x27|SHIFT, // )
330 0x25|SHIFT, // *
331 0x2e|SHIFT, // +
332 0x36, // ,
333 0x2d, // -
334 0x37, // .
335 0x38, // /
336 0x27, // 0
337 0x1e, // 1
338 0x1f, // 2
339 0x20, // 3
340 0x21, // 4
341 0x22, // 5
342 0x23, // 6
343 0x24, // 7
344 0x25, // 8
345 0x26, // 9
346 0x33|SHIFT, // :
347 0x33, // ;
348 0x36|SHIFT, // <
349 0x2e, // =
350 0x37|SHIFT, // >
351 0x38|SHIFT, // ?
352 0x1f|SHIFT, // @
353 0x04|SHIFT, // A
354 0x05|SHIFT, // B
355 0x06|SHIFT, // C
356 0x07|SHIFT, // D
357 0x08|SHIFT, // E
358 0x09|SHIFT, // F
359 0x0a|SHIFT, // G
360 0x0b|SHIFT, // H
361 0x0c|SHIFT, // I
362 0x0d|SHIFT, // J
363 0x0e|SHIFT, // K
364 0x0f|SHIFT, // L
365 0x10|SHIFT, // M
366 0x11|SHIFT, // N
367 0x12|SHIFT, // O
368 0x13|SHIFT, // P
369 0x14|SHIFT, // Q
370 0x15|SHIFT, // R
371 0x16|SHIFT, // S
372 0x17|SHIFT, // T
373 0x18|SHIFT, // U
374 0x19|SHIFT, // V
375 0x1a|SHIFT, // W
376 0x1b|SHIFT, // X
377 0x1c|SHIFT, // Y
378 0x1d|SHIFT, // Z
379 0x2f, // [
380 0x31, // bslash
381 0x30, // ]
382 0x23|SHIFT, // ^
383 0x2d|SHIFT, // _
384 0x35, // `
385 0x04, // a
386 0x05, // b
387 0x06, // c
388 0x07, // d
389 0x08, // e
390 0x09, // f
391 0x0a, // g
392 0x0b, // h
393 0x0c, // i
394 0x0d, // j
395 0x0e, // k
396 0x0f, // l
397 0x10, // m
398 0x11, // n
399 0x12, // o
400 0x13, // p
401 0x14, // q
402 0x15, // r
403 0x16, // s
404 0x17, // t
405 0x18, // u
406 0x19, // v
407 0x1a, // w
408 0x1b, // x
409 0x1c, // y
410 0x1d, // z
411 0x2f|SHIFT, //
412 0x31|SHIFT, // |
413 0x30|SHIFT, // }
414 0x35|SHIFT, // ~
415 0 // DEL
416 };
417
418 uint8_t USBPutChar(uint8_t c);
419
420 // press() adds the specified key (printing, non-printing, or modifier)
421 // to the persistent key report and sends the report. Because of the way
422 // USB HID works, the host acts like the key remains pressed until we
423 // call release(), releaseAll(), or otherwise clear the report and resend.
424 size_t Keyboard_::press(uint8_t k)
425 {
426 uint8_t i;
427 if (k >= 136) { // it's a non-printing key (not a modifier)
428 k = k - 136;
429 } else if (k >= 128) { // it's a modifier key
430 _keyReport.modifiers |= (1<<(k-128));
431 k = 0;
432 } else { // it's a printing key
433 k = pgm_read_byte(_asciimap + k);
434 if (!k) {
435 setWriteError();
436 return 0;
437 }
438 if (k & 0x80) { // it's a capital letter or other character reached with shift
439 _keyReport.modifiers |= 0x02; // the left shift modifier
440 k &= 0x7F;
441 }
442 }
443
444 // Add k to the key report only if it's not already present
445 // and if there is an empty slot.
446 if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
447 _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
448 _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
449
450 for (i=0; i<6; i++) {
451 if (_keyReport.keys[i] == 0x00) {
452 _keyReport.keys[i] = k;
453 break;
454 }
455 }
456 if (i == 6) {
457 setWriteError();
458 return 0;
459 }
460 }
461 sendReport(&_keyReport);
462 return 1;
463 }
464
465 // release() takes the specified key out of the persistent key report and
466 // sends the report. This tells the OS the key is no longer pressed and that
467 // it shouldn't be repeated any more.
468 size_t Keyboard_::release(uint8_t k)
469 {
470 uint8_t i;
471 if (k >= 136) { // it's a non-printing key (not a modifier)
472 k = k - 136;
473 } else if (k >= 128) { // it's a modifier key
474 _keyReport.modifiers &= ~(1<<(k-128));
475 k = 0;
476 } else { // it's a printing key
477 k = pgm_read_byte(_asciimap + k);
478 if (!k) {
479 return 0;
480 }
481 if (k & 0x80) { // it's a capital letter or other character reached with shift
482 _keyReport.modifiers &= ~(0x02); // the left shift modifier
483 k &= 0x7F;
484 }
485 }
486
487 // Test the key report to see if k is present. Clear it if it exists.
488 // Check all positions in case the key is present more than once (which it shouldn't be)
489 for (i=0; i<6; i++) {
490 if (0 != k && _keyReport.keys[i] == k) {
491 _keyReport.keys[i] = 0x00;
492 }
493 }
494
495 sendReport(&_keyReport);
496 return 1;
497 }
498
499 void Keyboard_::releaseAll(void)
500 {
501 _keyReport.keys[0] = 0;
502 _keyReport.keys[1] = 0;
503 _keyReport.keys[2] = 0;
504 _keyReport.keys[3] = 0;
505 _keyReport.keys[4] = 0;
506 _keyReport.keys[5] = 0;
507 _keyReport.modifiers = 0;
508 sendReport(&_keyReport);
509 }
510
511 size_t Keyboard_::write(uint8_t c)
512 {
513 uint8_t p = press(c); // Keydown
514 uint8_t r = release(c); // Keyup
515 return (p); // just return the result of press() since release() almost always returns 1
516 }
517
518 #endif
519
520 #endif /* if defined(USBCON) */
This diff has been collapsed as it changes many lines, (508 lines changed) Show them Hide them
@@ -0,0 +1,508
1 /*
2 HardwareSerial.cpp - Hardware serial library for Wiring
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 23 November 2006 by David A. Mellis
20 Modified 28 September 2010 by Mark Sproul
21 Modified 14 August 2012 by Alarus
22 */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <inttypes.h>
28 #include "Arduino.h"
29 #include "wiring_private.h"
30
31 // this next line disables the entire HardwareSerial.cpp,
32 // this is so I can support Attiny series and any other chip without a uart
33 #if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
34
35 #include "HardwareSerial.h"
36
37 /*
38 * on ATmega8, the uart and its bits are not numbered, so there is no "TXC0"
39 * definition.
40 */
41 #if !defined(TXC0)
42 #if defined(TXC)
43 #define TXC0 TXC
44 #elif defined(TXC1)
45 // Some devices have uart1 but no uart0
46 #define TXC0 TXC1
47 #else
48 #error TXC0 not definable in HardwareSerial.h
49 #endif
50 #endif
51
52 // Define constants and variables for buffering incoming serial data. We're
53 // using a ring buffer (I think), in which head is the index of the location
54 // to which to write the next incoming character and tail is the index of the
55 // location from which to read.
56 #if (RAMEND < 1000)
57 #define SERIAL_BUFFER_SIZE 16
58 #else
59 #define SERIAL_BUFFER_SIZE 64
60 #endif
61
62 struct ring_buffer
63 {
64 unsigned char buffer[SERIAL_BUFFER_SIZE];
65 volatile unsigned int head;
66 volatile unsigned int tail;
67 };
68
69 #if defined(USBCON)
70 ring_buffer rx_buffer = { { 0 }, 0, 0};
71 ring_buffer tx_buffer = { { 0 }, 0, 0};
72 #endif
73 #if defined(UBRRH) || defined(UBRR0H)
74 ring_buffer rx_buffer = { { 0 }, 0, 0 };
75 ring_buffer tx_buffer = { { 0 }, 0, 0 };
76 #endif
77 #if defined(UBRR1H)
78 ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
79 ring_buffer tx_buffer1 = { { 0 }, 0, 0 };
80 #endif
81 #if defined(UBRR2H)
82 ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
83 ring_buffer tx_buffer2 = { { 0 }, 0, 0 };
84 #endif
85 #if defined(UBRR3H)
86 ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
87 ring_buffer tx_buffer3 = { { 0 }, 0, 0 };
88 #endif
89
90 inline void store_char(unsigned char c, ring_buffer *buffer)
91 {
92 int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
93
94 // if we should be storing the received character into the location
95 // just before the tail (meaning that the head would advance to the
96 // current location of the tail), we're about to overflow the buffer
97 // and so we don't write the character or advance the head.
98 if (i != buffer->tail) {
99 buffer->buffer[buffer->head] = c;
100 buffer->head = i;
101 }
102 }
103
104 #if !defined(USART0_RX_vect) && defined(USART1_RX_vect)
105 // do nothing - on the 32u4 the first USART is USART1
106 #else
107 #if !defined(USART_RX_vect) && !defined(USART0_RX_vect) && \
108 !defined(USART_RXC_vect)
109 #error "Don't know what the Data Received vector is called for the first UART"
110 #else
111 void serialEvent() __attribute__((weak));
112 void serialEvent() {}
113 #define serialEvent_implemented
114 #if defined(USART_RX_vect)
115 ISR(USART_RX_vect)
116 #elif defined(USART0_RX_vect)
117 ISR(USART0_RX_vect)
118 #elif defined(USART_RXC_vect)
119 ISR(USART_RXC_vect) // ATmega8
120 #endif
121 {
122 #if defined(UDR0)
123 if (bit_is_clear(UCSR0A, UPE0)) {
124 unsigned char c = UDR0;
125 store_char(c, &rx_buffer);
126 } else {
127 unsigned char c = UDR0;
128 };
129 #elif defined(UDR)
130 if (bit_is_clear(UCSRA, PE)) {
131 unsigned char c = UDR;
132 store_char(c, &rx_buffer);
133 } else {
134 unsigned char c = UDR;
135 };
136 #else
137 #error UDR not defined
138 #endif
139 }
140 #endif
141 #endif
142
143 #if defined(USART1_RX_vect)
144 void serialEvent1() __attribute__((weak));
145 void serialEvent1() {}
146 #define serialEvent1_implemented
147 ISR(USART1_RX_vect)
148 {
149 if (bit_is_clear(UCSR1A, UPE1)) {
150 unsigned char c = UDR1;
151 store_char(c, &rx_buffer1);
152 } else {
153 unsigned char c = UDR1;
154 };
155 }
156 #endif
157
158 #if defined(USART2_RX_vect) && defined(UDR2)
159 void serialEvent2() __attribute__((weak));
160 void serialEvent2() {}
161 #define serialEvent2_implemented
162 ISR(USART2_RX_vect)
163 {
164 if (bit_is_clear(UCSR2A, UPE2)) {
165 unsigned char c = UDR2;
166 store_char(c, &rx_buffer2);
167 } else {
168 unsigned char c = UDR2;
169 };
170 }
171 #endif
172
173 #if defined(USART3_RX_vect) && defined(UDR3)
174 void serialEvent3() __attribute__((weak));
175 void serialEvent3() {}
176 #define serialEvent3_implemented
177 ISR(USART3_RX_vect)
178 {
179 if (bit_is_clear(UCSR3A, UPE3)) {
180 unsigned char c = UDR3;
181 store_char(c, &rx_buffer3);
182 } else {
183 unsigned char c = UDR3;
184 };
185 }
186 #endif
187
188 void serialEventRun(void)
189 {
190 #ifdef serialEvent_implemented
191 if (Serial.available()) serialEvent();
192 #endif
193 #ifdef serialEvent1_implemented
194 if (Serial1.available()) serialEvent1();
195 #endif
196 #ifdef serialEvent2_implemented
197 if (Serial2.available()) serialEvent2();
198 #endif
199 #ifdef serialEvent3_implemented
200 if (Serial3.available()) serialEvent3();
201 #endif
202 }
203
204
205 #if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect)
206 // do nothing - on the 32u4 the first USART is USART1
207 #else
208 #if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect)
209 #error "Don't know what the Data Register Empty vector is called for the first UART"
210 #else
211 #if defined(UART0_UDRE_vect)
212 ISR(UART0_UDRE_vect)
213 #elif defined(UART_UDRE_vect)
214 ISR(UART_UDRE_vect)
215 #elif defined(USART0_UDRE_vect)
216 ISR(USART0_UDRE_vect)
217 #elif defined(USART_UDRE_vect)
218 ISR(USART_UDRE_vect)
219 #endif
220 {
221 if (tx_buffer.head == tx_buffer.tail) {
222 // Buffer empty, so disable interrupts
223 #if defined(UCSR0B)
224 cbi(UCSR0B, UDRIE0);
225 #else
226 cbi(UCSRB, UDRIE);
227 #endif
228 }
229 else {
230 // There is more data in the output buffer. Send the next byte
231 unsigned char c = tx_buffer.buffer[tx_buffer.tail];
232 tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
233
234 #if defined(UDR0)
235 UDR0 = c;
236 #elif defined(UDR)
237 UDR = c;
238 #else
239 #error UDR not defined
240 #endif
241 }
242 }
243 #endif
244 #endif
245
246 #ifdef USART1_UDRE_vect
247 ISR(USART1_UDRE_vect)
248 {
249 if (tx_buffer1.head == tx_buffer1.tail) {
250 // Buffer empty, so disable interrupts
251 cbi(UCSR1B, UDRIE1);
252 }
253 else {
254 // There is more data in the output buffer. Send the next byte
255 unsigned char c = tx_buffer1.buffer[tx_buffer1.tail];
256 tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE;
257
258 UDR1 = c;
259 }
260 }
261 #endif
262
263 #ifdef USART2_UDRE_vect
264 ISR(USART2_UDRE_vect)
265 {
266 if (tx_buffer2.head == tx_buffer2.tail) {
267 // Buffer empty, so disable interrupts
268 cbi(UCSR2B, UDRIE2);
269 }
270 else {
271 // There is more data in the output buffer. Send the next byte
272 unsigned char c = tx_buffer2.buffer[tx_buffer2.tail];
273 tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE;
274
275 UDR2 = c;
276 }
277 }
278 #endif
279
280 #ifdef USART3_UDRE_vect
281 ISR(USART3_UDRE_vect)
282 {
283 if (tx_buffer3.head == tx_buffer3.tail) {
284 // Buffer empty, so disable interrupts
285 cbi(UCSR3B, UDRIE3);
286 }
287 else {
288 // There is more data in the output buffer. Send the next byte
289 unsigned char c = tx_buffer3.buffer[tx_buffer3.tail];
290 tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE;
291
292 UDR3 = c;
293 }
294 }
295 #endif
296
297
298 // Constructors ////////////////////////////////////////////////////////////////
299
300 HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
301 volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
302 volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
303 volatile uint8_t *ucsrc, volatile uint8_t *udr,
304 uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
305 {
306 _rx_buffer = rx_buffer;
307 _tx_buffer = tx_buffer;
308 _ubrrh = ubrrh;
309 _ubrrl = ubrrl;
310 _ucsra = ucsra;
311 _ucsrb = ucsrb;
312 _ucsrc = ucsrc;
313 _udr = udr;
314 _rxen = rxen;
315 _txen = txen;
316 _rxcie = rxcie;
317 _udrie = udrie;
318 _u2x = u2x;
319 }
320
321 // Public Methods //////////////////////////////////////////////////////////////
322
323 void HardwareSerial::begin(unsigned long baud)
324 {
325 uint16_t baud_setting;
326 bool use_u2x = true;
327
328 #if F_CPU == 16000000UL
329 // hardcoded exception for compatibility with the bootloader shipped
330 // with the Duemilanove and previous boards and the firmware on the 8U2
331 // on the Uno and Mega 2560.
332 if (baud == 57600) {
333 use_u2x = false;
334 }
335 #endif
336
337 try_again:
338
339 if (use_u2x) {
340 *_ucsra = 1 << _u2x;
341 baud_setting = (F_CPU / 4 / baud - 1) / 2;
342 } else {
343 *_ucsra = 0;
344 baud_setting = (F_CPU / 8 / baud - 1) / 2;
345 }
346
347 if ((baud_setting > 4095) && use_u2x)
348 {
349 use_u2x = false;
350 goto try_again;
351 }
352
353 // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
354 *_ubrrh = baud_setting >> 8;
355 *_ubrrl = baud_setting;
356
357 transmitting = false;
358
359 sbi(*_ucsrb, _rxen);
360 sbi(*_ucsrb, _txen);
361 sbi(*_ucsrb, _rxcie);
362 cbi(*_ucsrb, _udrie);
363 }
364
365 void HardwareSerial::begin(unsigned long baud, byte config)
366 {
367 uint16_t baud_setting;
368 uint8_t current_config;
369 bool use_u2x = true;
370
371 #if F_CPU == 16000000UL
372 // hardcoded exception for compatibility with the bootloader shipped
373 // with the Duemilanove and previous boards and the firmware on the 8U2
374 // on the Uno and Mega 2560.
375 if (baud == 57600) {
376 use_u2x = false;
377 }
378 #endif
379
380 try_again:
381
382 if (use_u2x) {
383 *_ucsra = 1 << _u2x;
384 baud_setting = (F_CPU / 4 / baud - 1) / 2;
385 } else {
386 *_ucsra = 0;
387 baud_setting = (F_CPU / 8 / baud - 1) / 2;
388 }
389
390 if ((baud_setting > 4095) && use_u2x)
391 {
392 use_u2x = false;
393 goto try_again;
394 }
395
396 // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
397 *_ubrrh = baud_setting >> 8;
398 *_ubrrl = baud_setting;
399
400 //set the data bits, parity, and stop bits
401 #if defined(__AVR_ATmega8__)
402 config |= 0x80; // select UCSRC register (shared with UBRRH)
403 #endif
404 *_ucsrc = config;
405
406 sbi(*_ucsrb, _rxen);
407 sbi(*_ucsrb, _txen);
408 sbi(*_ucsrb, _rxcie);
409 cbi(*_ucsrb, _udrie);
410 }
411
412 void HardwareSerial::end()
413 {
414 // wait for transmission of outgoing data
415 while (_tx_buffer->head != _tx_buffer->tail)
416 ;
417
418 cbi(*_ucsrb, _rxen);
419 cbi(*_ucsrb, _txen);
420 cbi(*_ucsrb, _rxcie);
421 cbi(*_ucsrb, _udrie);
422
423 // clear any received data
424 _rx_buffer->head = _rx_buffer->tail;
425 }
426
427 int HardwareSerial::available(void)
428 {
429 return (int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
430 }
431
432 int HardwareSerial::peek(void)
433 {
434 if (_rx_buffer->head == _rx_buffer->tail) {
435 return -1;
436 } else {
437 return _rx_buffer->buffer[_rx_buffer->tail];
438 }
439 }
440
441 int HardwareSerial::read(void)
442 {
443 // if the head isn't ahead of the tail, we don't have any characters
444 if (_rx_buffer->head == _rx_buffer->tail) {
445 return -1;
446 } else {
447 unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
448 _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE;
449 return c;
450 }
451 }
452
453 void HardwareSerial::flush()
454 {
455 // UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY && SENT
456 while (transmitting && ! (*_ucsra & _BV(TXC0)));
457 transmitting = false;
458 }
459
460 size_t HardwareSerial::write(uint8_t c)
461 {
462 int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
463
464 // If the output buffer is full, there's nothing for it other than to
465 // wait for the interrupt handler to empty it a bit
466 // ???: return 0 here instead?
467 while (i == _tx_buffer->tail)
468 ;
469
470 _tx_buffer->buffer[_tx_buffer->head] = c;
471 _tx_buffer->head = i;
472
473 sbi(*_ucsrb, _udrie);
474 // clear the TXC bit -- "can be cleared by writing a one to its bit location"
475 transmitting = true;
476 sbi(*_ucsra, TXC0);
477
478 return 1;
479 }
480
481 HardwareSerial::operator bool() {
482 return true;
483 }
484
485 // Preinstantiate Objects //////////////////////////////////////////////////////
486
487 #if defined(UBRRH) && defined(UBRRL)
488 HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
489 #elif defined(UBRR0H) && defined(UBRR0L)
490 HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
491 #elif defined(USBCON)
492 // do nothing - Serial object and buffers are initialized in CDC code
493 #else
494 #error no serial port defined (port 0)
495 #endif
496
497 #if defined(UBRR1H)
498 HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
499 #endif
500 #if defined(UBRR2H)
501 HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
502 #endif
503 #if defined(UBRR3H)
504 HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
505 #endif
506
507 #endif // whole file
508
@@ -0,0 +1,115
1 /*
2 HardwareSerial.h - Hardware serial library for Wiring
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 28 September 2010 by Mark Sproul
20 Modified 14 August 2012 by Alarus
21 */
22
23 #ifndef HardwareSerial_h
24 #define HardwareSerial_h
25
26 #include <inttypes.h>
27
28 #include "Stream.h"
29
30 struct ring_buffer;
31
32 class HardwareSerial : public Stream
33 {
34 private:
35 ring_buffer *_rx_buffer;
36 ring_buffer *_tx_buffer;
37 volatile uint8_t *_ubrrh;
38 volatile uint8_t *_ubrrl;
39 volatile uint8_t *_ucsra;
40 volatile uint8_t *_ucsrb;
41 volatile uint8_t *_ucsrc;
42 volatile uint8_t *_udr;
43 uint8_t _rxen;
44 uint8_t _txen;
45 uint8_t _rxcie;
46 uint8_t _udrie;
47 uint8_t _u2x;
48 bool transmitting;
49 public:
50 HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
51 volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
52 volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
53 volatile uint8_t *ucsrc, volatile uint8_t *udr,
54 uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x);
55 void begin(unsigned long);
56 void begin(unsigned long, uint8_t);
57 void end();
58 virtual int available(void);
59 virtual int peek(void);
60 virtual int read(void);
61 virtual void flush(void);
62 virtual size_t write(uint8_t);
63 inline size_t write(unsigned long n) { return write((uint8_t)n); }
64 inline size_t write(long n) { return write((uint8_t)n); }
65 inline size_t write(unsigned int n) { return write((uint8_t)n); }
66 inline size_t write(int n) { return write((uint8_t)n); }
67 using Print::write; // pull in write(str) and write(buf, size) from Print
68 operator bool();
69 };
70
71 // Define config for Serial.begin(baud, config);
72 #define SERIAL_5N1 0x00
73 #define SERIAL_6N1 0x02
74 #define SERIAL_7N1 0x04
75 #define SERIAL_8N1 0x06
76 #define SERIAL_5N2 0x08
77 #define SERIAL_6N2 0x0A
78 #define SERIAL_7N2 0x0C
79 #define SERIAL_8N2 0x0E
80 #define SERIAL_5E1 0x20
81 #define SERIAL_6E1 0x22
82 #define SERIAL_7E1 0x24
83 #define SERIAL_8E1 0x26
84 #define SERIAL_5E2 0x28
85 #define SERIAL_6E2 0x2A
86 #define SERIAL_7E2 0x2C
87 #define SERIAL_8E2 0x2E
88 #define SERIAL_5O1 0x30
89 #define SERIAL_6O1 0x32
90 #define SERIAL_7O1 0x34
91 #define SERIAL_8O1 0x36
92 #define SERIAL_5O2 0x38
93 #define SERIAL_6O2 0x3A
94 #define SERIAL_7O2 0x3C
95 #define SERIAL_8O2 0x3E
96
97 #if defined(UBRRH) || defined(UBRR0H)
98 extern HardwareSerial Serial;
99 #elif defined(USBCON)
100 #include "USBAPI.h"
101 // extern HardwareSerial Serial_;
102 #endif
103 #if defined(UBRR1H)
104 extern HardwareSerial Serial1;
105 #endif
106 #if defined(UBRR2H)
107 extern HardwareSerial Serial2;
108 #endif
109 #if defined(UBRR3H)
110 extern HardwareSerial Serial3;
111 #endif
112
113 extern void serialEventRun(void) __attribute__((weak));
114
115 #endif
@@ -0,0 +1,74
1 /*
2 IPAddress.cpp - Base class that provides IPAddress
3 Copyright (c) 2011 Adrian McEwen. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <Arduino.h>
21 #include <IPAddress.h>
22
23 IPAddress::IPAddress()
24 {
25 memset(_address, 0, sizeof(_address));
26 }
27
28 IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
29 {
30 _address[0] = first_octet;
31 _address[1] = second_octet;
32 _address[2] = third_octet;
33 _address[3] = fourth_octet;
34 }
35
36 IPAddress::IPAddress(uint32_t address)
37 {
38 memcpy(_address, &address, sizeof(_address));
39 }
40
41 IPAddress::IPAddress(const uint8_t *address)
42 {
43 memcpy(_address, address, sizeof(_address));
44 }
45
46 IPAddress& IPAddress::operator=(const uint8_t *address)
47 {
48 memcpy(_address, address, sizeof(_address));
49 return *this;
50 }
51
52 IPAddress& IPAddress::operator=(uint32_t address)
53 {
54 memcpy(_address, (const uint8_t *)&address, sizeof(_address));
55 return *this;
56 }
57
58 bool IPAddress::operator==(const uint8_t* addr)
59 {
60 return memcmp(addr, _address, sizeof(_address)) == 0;
61 }
62
63 size_t IPAddress::printTo(Print& p) const
64 {
65 size_t n = 0;
66 for (int i =0; i < 3; i++)
67 {
68 n += p.print(_address[i], DEC);
69 n += p.print('.');
70 }
71 n += p.print(_address[3], DEC);
72 return n;
73 }
74
@@ -0,0 +1,70
1 /*
2 IPAddress.h - Base class that provides IPAddress
3 Copyright (c) 2011 Adrian McEwen. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef IPAddress_h
21 #define IPAddress_h
22
23 #include <Printable.h>
24
25 // A class to make it easier to handle and pass around IP addresses
26
27 class IPAddress : public Printable {
28 private:
29 uint8_t _address[4]; // IPv4 address
30 // Access the raw byte array containing the address. Because this returns a pointer
31 // to the internal structure rather than a copy of the address this function should only
32 // be used when you know that the usage of the returned uint8_t* will be transient and not
33 // stored.
34 uint8_t* raw_address() { return _address; };
35
36 public:
37 // Constructors
38 IPAddress();
39 IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
40 IPAddress(uint32_t address);
41 IPAddress(const uint8_t *address);
42
43 // Overloaded cast operator to allow IPAddress objects to be used where a pointer
44 // to a four-byte uint8_t array is expected
45 operator uint32_t() { return *((uint32_t*)_address); };
46 bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
47 bool operator==(const uint8_t* addr);
48
49 // Overloaded index operator to allow getting and setting individual octets of the address
50 uint8_t operator[](int index) const { return _address[index]; };
51 uint8_t& operator[](int index) { return _address[index]; };
52
53 // Overloaded copy operators to allow initialisation of IPAddress objects from other types
54 IPAddress& operator=(const uint8_t *address);
55 IPAddress& operator=(uint32_t address);
56
57 virtual size_t printTo(Print& p) const;
58
59 friend class EthernetClass;
60 friend class UDP;
61 friend class Client;
62 friend class Server;
63 friend class DhcpClass;
64 friend class DNSClient;
65 };
66
67 const IPAddress INADDR_NONE(0,0,0,0);
68
69
70 #endif
@@ -0,0 +1,23
1
2 #ifndef __PLATFORM_H__
3 #define __PLATFORM_H__
4
5 #include <inttypes.h>
6 #include <avr/pgmspace.h>
7 #include <avr/eeprom.h>
8 #include <avr/interrupt.h>
9 #include <util/delay.h>
10
11 typedef unsigned char u8;
12 typedef unsigned short u16;
13 typedef unsigned long u32;
14
15 #include "Arduino.h"
16
17 #if defined(USBCON)
18 #include "USBDesc.h"
19 #include "USBCore.h"
20 #include "USBAPI.h"
21 #endif /* if defined(USBCON) */
22
23 #endif
@@ -0,0 +1,264
1 /*
2 Print.cpp - Base class that provides print() and println()
3 Copyright (c) 2008 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 23 November 2006 by David A. Mellis
20 */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <math.h>
26 #include "Arduino.h"
27
28 #include "Print.h"
29
30 // Public Methods //////////////////////////////////////////////////////////////
31
32 /* default implementation: may be overridden */
33 size_t Print::write(const uint8_t *buffer, size_t size)
34 {
35 size_t n = 0;
36 while (size--) {
37 n += write(*buffer++);
38 }
39 return n;
40 }
41
42 size_t Print::print(const __FlashStringHelper *ifsh)
43 {
44 PGM_P p = reinterpret_cast<PGM_P>(ifsh);
45 size_t n = 0;
46 while (1) {
47 unsigned char c = pgm_read_byte(p++);
48 if (c == 0) break;
49 n += write(c);
50 }
51 return n;
52 }
53
54 size_t Print::print(const String &s)
55 {
56 return write(s.c_str(), s.length());
57 }
58
59 size_t Print::print(const char str[])
60 {
61 return write(str);
62 }
63
64 size_t Print::print(char c)
65 {
66 return write(c);
67 }
68
69 size_t Print::print(unsigned char b, int base)
70 {
71 return print((unsigned long) b, base);
72 }
73
74 size_t Print::print(int n, int base)
75 {
76 return print((long) n, base);
77 }
78
79 size_t Print::print(unsigned int n, int base)
80 {
81 return print((unsigned long) n, base);
82 }
83
84 size_t Print::print(long n, int base)
85 {
86 if (base == 0) {
87 return write(n);
88 } else if (base == 10) {
89 if (n < 0) {
90 int t = print('-');
91 n = -n;
92 return printNumber(n, 10) + t;
93 }
94 return printNumber(n, 10);
95 } else {
96 return printNumber(n, base);
97 }
98 }
99
100 size_t Print::print(unsigned long n, int base)
101 {
102 if (base == 0) return write(n);
103 else return printNumber(n, base);
104 }
105
106 size_t Print::print(double n, int digits)
107 {
108 return printFloat(n, digits);
109 }
110
111 size_t Print::println(const __FlashStringHelper *ifsh)
112 {
113 size_t n = print(ifsh);
114 n += println();
115 return n;
116 }
117
118 size_t Print::print(const Printable& x)
119 {
120 return x.printTo(*this);
121 }
122
123 size_t Print::println(void)
124 {
125 size_t n = print('\r');
126 n += print('\n');
127 return n;
128 }
129
130 size_t Print::println(const String &s)
131 {
132 size_t n = print(s);
133 n += println();
134 return n;
135 }
136
137 size_t Print::println(const char c[])
138 {
139 size_t n = print(c);
140 n += println();
141 return n;
142 }
143
144 size_t Print::println(char c)
145 {
146 size_t n = print(c);
147 n += println();
148 return n;
149 }
150
151 size_t Print::println(unsigned char b, int base)
152 {
153 size_t n = print(b, base);
154 n += println();
155 return n;
156 }
157
158 size_t Print::println(int num, int base)
159 {
160 size_t n = print(num, base);
161 n += println();
162 return n;
163 }
164
165 size_t Print::println(unsigned int num, int base)
166 {
167 size_t n = print(num, base);
168 n += println();
169 return n;
170 }
171
172 size_t Print::println(long num, int base)
173 {
174 size_t n = print(num, base);
175 n += println();
176 return n;
177 }
178
179 size_t Print::println(unsigned long num, int base)
180 {
181 size_t n = print(num, base);
182 n += println();
183 return n;
184 }
185
186 size_t Print::println(double num, int digits)
187 {
188 size_t n = print(num, digits);
189 n += println();
190 return n;
191 }
192
193 size_t Print::println(const Printable& x)
194 {
195 size_t n = print(x);
196 n += println();
197 return n;
198 }
199
200 // Private Methods /////////////////////////////////////////////////////////////
201
202 size_t Print::printNumber(unsigned long n, uint8_t base) {
203 char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
204 char *str = &buf[sizeof(buf) - 1];
205
206 *str = '\0';
207
208 // prevent crash if called with base == 1
209 if (base < 2) base = 10;
210
211 do {
212 unsigned long m = n;
213 n /= base;
214 char c = m - base * n;
215 *--str = c < 10 ? c + '0' : c + 'A' - 10;
216 } while(n);
217
218 return write(str);
219 }
220
221 size_t Print::printFloat(double number, uint8_t digits)
222 {
223 size_t n = 0;
224
225 if (isnan(number)) return print("nan");
226 if (isinf(number)) return print("inf");
227 if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
228 if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
229
230 // Handle negative numbers
231 if (number < 0.0)
232 {
233 n += print('-');
234 number = -number;
235 }
236
237 // Round correctly so that print(1.999, 2) prints as "2.00"
238 double rounding = 0.5;
239 for (uint8_t i=0; i<digits; ++i)
240 rounding /= 10.0;
241
242 number += rounding;
243
244 // Extract the integer part of the number and print it
245 unsigned long int_part = (unsigned long)number;
246 double remainder = number - (double)int_part;
247 n += print(int_part);
248
249 // Print the decimal point, but only if there are digits beyond
250 if (digits > 0) {
251 n += print(".");
252 }
253
254 // Extract digits from the remainder one at a time
255 while (digits-- > 0)
256 {
257 remainder *= 10.0;
258 int toPrint = int(remainder);
259 n += print(toPrint);
260 remainder -= toPrint;
261 }
262
263 return n;
264 }
@@ -0,0 +1,84
1 /*
2 Print.h - Base class that provides print() and println()
3 Copyright (c) 2008 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef Print_h
21 #define Print_h
22
23 #include <inttypes.h>
24 #include <stdio.h> // for size_t
25
26 #include "WString.h"
27 #include "Printable.h"
28
29 #define DEC 10
30 #define HEX 16
31 #define OCT 8
32 #define BIN 2
33
34 class Print
35 {
36 private:
37 int write_error;
38 size_t printNumber(unsigned long, uint8_t);
39 size_t printFloat(double, uint8_t);
40 protected:
41 void setWriteError(int err = 1) { write_error = err; }
42 public:
43 Print() : write_error(0) {}
44
45 int getWriteError() { return write_error; }
46 void clearWriteError() { setWriteError(0); }
47
48 virtual size_t write(uint8_t) = 0;
49 size_t write(const char *str) {
50 if (str == NULL) return 0;
51 return write((const uint8_t *)str, strlen(str));
52 }
53 virtual size_t write(const uint8_t *buffer, size_t size);
54 size_t write(const char *buffer, size_t size) {
55 return write((const uint8_t *)buffer, size);
56 }
57
58 size_t print(const __FlashStringHelper *);
59 size_t print(const String &);
60 size_t print(const char[]);
61 size_t print(char);
62 size_t print(unsigned char, int = DEC);
63 size_t print(int, int = DEC);
64 size_t print(unsigned int, int = DEC);
65 size_t print(long, int = DEC);
66 size_t print(unsigned long, int = DEC);
67 size_t print(double, int = 2);
68 size_t print(const Printable&);
69
70 size_t println(const __FlashStringHelper *);
71 size_t println(const String &s);
72 size_t println(const char[]);
73 size_t println(char);
74 size_t println(unsigned char, int = DEC);
75 size_t println(int, int = DEC);
76 size_t println(unsigned int, int = DEC);
77 size_t println(long, int = DEC);
78 size_t println(unsigned long, int = DEC);
79 size_t println(double, int = 2);
80 size_t println(const Printable&);
81 size_t println(void);
82 };
83
84 #endif
@@ -0,0 +1,40
1 /*
2 Printable.h - Interface class that allows printing of complex types
3 Copyright (c) 2011 Adrian McEwen. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef Printable_h
21 #define Printable_h
22
23 #include <new.h>
24
25 class Print;
26
27 /** The Printable class provides a way for new classes to allow themselves to be printed.
28 By deriving from Printable and implementing the printTo method, it will then be possible
29 for users to print out instances of this class by passing them into the usual
30 Print::print and Print::println methods.
31 */
32
33 class Printable
34 {
35 public:
36 virtual size_t printTo(Print& p) const = 0;
37 };
38
39 #endif
40
@@ -0,0 +1,28
1 /*
2 Server.h - Base class that provides Server
3 Copyright (c) 2011 Adrian McEwen. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef server_h
21 #define server_h
22
23 class Server : public Print {
24 public:
25 virtual void begin() =0;
26 };
27
28 #endif
@@ -0,0 +1,270
1 /*
2 Stream.cpp - adds parsing methods to Stream class
3 Copyright (c) 2008 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Created July 2011
20 parsing functions based on TextFinder library by Michael Margolis
21 */
22
23 #include "Arduino.h"
24 #include "Stream.h"
25
26 #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
27 #define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
28
29 // private method to read stream with timeout
30 int Stream::timedRead()
31 {
32 int c;
33 _startMillis = millis();
34 do {
35 c = read();
36 if (c >= 0) return c;
37 } while(millis() - _startMillis < _timeout);
38 return -1; // -1 indicates timeout
39 }
40
41 // private method to peek stream with timeout
42 int Stream::timedPeek()
43 {
44 int c;
45 _startMillis = millis();
46 do {
47 c = peek();
48 if (c >= 0) return c;
49 } while(millis() - _startMillis < _timeout);
50 return -1; // -1 indicates timeout
51 }
52
53 // returns peek of the next digit in the stream or -1 if timeout
54 // discards non-numeric characters
55 int Stream::peekNextDigit()
56 {
57 int c;
58 while (1) {
59 c = timedPeek();
60 if (c < 0) return c; // timeout
61 if (c == '-') return c;
62 if (c >= '0' && c <= '9') return c;
63 read(); // discard non-numeric
64 }
65 }
66
67 // Public Methods
68 //////////////////////////////////////////////////////////////
69
70 void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
71 {
72 _timeout = timeout;
73 }
74
75 // find returns true if the target string is found
76 bool Stream::find(char *target)
77 {
78 return findUntil(target, "");
79 }
80
81 // reads data from the stream until the target string of given length is found
82 // returns true if target string is found, false if timed out
83 bool Stream::find(char *target, size_t length)
84 {
85 return findUntil(target, length, NULL, 0);
86 }
87
88 // as find but search ends if the terminator string is found
89 bool Stream::findUntil(char *target, char *terminator)
90 {
91 return findUntil(target, strlen(target), terminator, strlen(terminator));
92 }
93
94 // reads data from the stream until the target string of the given length is found
95 // search terminated if the terminator string is found
96 // returns true if target string is found, false if terminated or timed out
97 bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
98 {
99 size_t index = 0; // maximum target string length is 64k bytes!
100 size_t termIndex = 0;
101 int c;
102
103 if( *target == 0)
104 return true; // return true if target is a null string
105 while( (c = timedRead()) > 0){
106
107 if(c != target[index])
108 index = 0; // reset index if any char does not match
109
110 if( c == target[index]){
111 //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
112 if(++index >= targetLen){ // return true if all chars in the target match
113 return true;
114 }
115 }
116
117 if(termLen > 0 && c == terminator[termIndex]){
118 if(++termIndex >= termLen)
119 return false; // return false if terminate string found before target string
120 }
121 else
122 termIndex = 0;
123 }
124 return false;
125 }
126
127
128 // returns the first valid (long) integer value from the current position.
129 // initial characters that are not digits (or the minus sign) are skipped
130 // function is terminated by the first character that is not a digit.
131 long Stream::parseInt()
132 {
133 return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
134 }
135
136 // as above but a given skipChar is ignored
137 // this allows format characters (typically commas) in values to be ignored
138 long Stream::parseInt(char skipChar)
139 {
140 boolean isNegative = false;
141 long value = 0;
142 int c;
143
144 c = peekNextDigit();
145 // ignore non numeric leading characters
146 if(c < 0)
147 return 0; // zero returned if timeout
148
149 do{
150 if(c == skipChar)
151 ; // ignore this charactor
152 else if(c == '-')
153 isNegative = true;
154 else if(c >= '0' && c <= '9') // is c a digit?
155 value = value * 10 + c - '0';
156 read(); // consume the character we got with peek
157 c = timedPeek();
158 }
159 while( (c >= '0' && c <= '9') || c == skipChar );
160
161 if(isNegative)
162 value = -value;
163 return value;
164 }
165
166
167 // as parseInt but returns a floating point value
168 float Stream::parseFloat()
169 {
170 return parseFloat(NO_SKIP_CHAR);
171 }
172
173 // as above but the given skipChar is ignored
174 // this allows format characters (typically commas) in values to be ignored
175 float Stream::parseFloat(char skipChar){
176 boolean isNegative = false;
177 boolean isFraction = false;
178 long value = 0;
179 char c;
180 float fraction = 1.0;
181
182 c = peekNextDigit();
183 // ignore non numeric leading characters
184 if(c < 0)
185 return 0; // zero returned if timeout
186
187 do{
188 if(c == skipChar)
189 ; // ignore
190 else if(c == '-')
191 isNegative = true;
192 else if (c == '.')
193 isFraction = true;
194 else if(c >= '0' && c <= '9') { // is c a digit?
195 value = value * 10 + c - '0';
196 if(isFraction)
197 fraction *= 0.1;
198 }
199 read(); // consume the character we got with peek
200 c = timedPeek();
201 }
202 while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
203
204 if(isNegative)
205 value = -value;
206 if(isFraction)
207 return value * fraction;
208 else
209 return value;
210 }
211
212 // read characters from stream into buffer
213 // terminates if length characters have been read, or timeout (see setTimeout)
214 // returns the number of characters placed in the buffer
215 // the buffer is NOT null terminated.
216 //
217 size_t Stream::readBytes(char *buffer, size_t length)
218 {
219 size_t count = 0;
220 while (count < length) {
221 int c = timedRead();
222 if (c < 0) break;
223 *buffer++ = (char)c;
224 count++;
225 }
226 return count;
227 }
228
229
230 // as readBytes with terminator character
231 // terminates if length characters have been read, timeout, or if the terminator character detected
232 // returns the number of characters placed in the buffer (0 means no valid data found)
233
234 size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
235 {
236 if (length < 1) return 0;
237 size_t index = 0;
238 while (index < length) {
239 int c = timedRead();
240 if (c < 0 || c == terminator) break;
241 *buffer++ = (char)c;
242 index++;
243 }
244 return index; // return number of characters, not including null terminator
245 }
246
247 String Stream::readString()
248 {
249 String ret;
250 int c = timedRead();
251 while (c >= 0)
252 {
253 ret += (char)c;
254 c = timedRead();
255 }
256 return ret;
257 }
258
259 String Stream::readStringUntil(char terminator)
260 {
261 String ret;
262 int c = timedRead();
263 while (c >= 0 && c != terminator)
264 {
265 ret += (char)c;
266 c = timedRead();
267 }
268 return ret;
269 }
270
@@ -0,0 +1,96
1 /*
2 Stream.h - base class for character-based streams.
3 Copyright (c) 2010 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 parsing functions based on TextFinder library by Michael Margolis
20 */
21
22 #ifndef Stream_h
23 #define Stream_h
24
25 #include <inttypes.h>
26 #include "Print.h"
27
28 // compatability macros for testing
29 /*
30 #define getInt() parseInt()
31 #define getInt(skipChar) parseInt(skipchar)
32 #define getFloat() parseFloat()
33 #define getFloat(skipChar) parseFloat(skipChar)
34 #define getString( pre_string, post_string, buffer, length)
35 readBytesBetween( pre_string, terminator, buffer, length)
36 */
37
38 class Stream : public Print
39 {
40 protected:
41 unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
42 unsigned long _startMillis; // used for timeout measurement
43 int timedRead(); // private method to read stream with timeout
44 int timedPeek(); // private method to peek stream with timeout
45 int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
46
47 public:
48 virtual int available() = 0;
49 virtual int read() = 0;
50 virtual int peek() = 0;
51 virtual void flush() = 0;
52
53 Stream() {_timeout=1000;}
54
55 // parsing methods
56
57 void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
58
59 bool find(char *target); // reads data from the stream until the target string is found
60 // returns true if target string is found, false if timed out (see setTimeout)
61
62 bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
63 // returns true if target string is found, false if timed out
64
65 bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
66
67 bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
68
69
70 long parseInt(); // returns the first valid (long) integer value from the current position.
71 // initial characters that are not digits (or the minus sign) are skipped
72 // integer is terminated by the first character that is not a digit.
73
74 float parseFloat(); // float version of parseInt
75
76 size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
77 // terminates if length characters have been read or timeout (see setTimeout)
78 // returns the number of characters placed in the buffer (0 means no valid data found)
79
80 size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
81 // terminates if length characters have been read, timeout, or if the terminator character detected
82 // returns the number of characters placed in the buffer (0 means no valid data found)
83
84 // Arduino String functions to be added here
85 String readString();
86 String readStringUntil(char terminator);
87
88 protected:
89 long parseInt(char skipChar); // as above but the given skipChar is ignored
90 // as above but the given skipChar is ignored
91 // this allows format characters (typically commas) in values to be ignored
92
93 float parseFloat(char skipChar); // as above but the given skipChar is ignored
94 };
95
96 #endif
This diff has been collapsed as it changes many lines, (616 lines changed) Show them Hide them
@@ -0,0 +1,616
1 /* Tone.cpp
2
3 A Tone Generator Library
4
5 Written by Brett Hagman
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
21 Version Modified By Date Comments
22 ------- ----------- -------- --------
23 0001 B Hagman 09/08/02 Initial coding
24 0002 B Hagman 09/08/18 Multiple pins
25 0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
26 0004 B Hagman 09/09/26 Fixed problems with ATmega8
27 0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
28 09/11/25 Changed pin toggle method to XOR
29 09/11/25 Fixed timer0 from being excluded
30 0006 D Mellis 09/12/29 Replaced objects with functions
31 0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
32 0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY
33 *************************************************/
34
35 #include <avr/interrupt.h>
36 #include <avr/pgmspace.h>
37 #include "Arduino.h"
38 #include "pins_arduino.h"
39
40 #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
41 #define TCCR2A TCCR2
42 #define TCCR2B TCCR2
43 #define COM2A1 COM21
44 #define COM2A0 COM20
45 #define OCR2A OCR2
46 #define TIMSK2 TIMSK
47 #define OCIE2A OCIE2
48 #define TIMER2_COMPA_vect TIMER2_COMP_vect
49 #define TIMSK1 TIMSK
50 #endif
51
52 // timerx_toggle_count:
53 // > 0 - duration specified
54 // = 0 - stopped
55 // < 0 - infinitely (until stop() method called, or new play() called)
56
57 #if !defined(__AVR_ATmega8__)
58 volatile long timer0_toggle_count;
59 volatile uint8_t *timer0_pin_port;
60 volatile uint8_t timer0_pin_mask;
61 #endif
62
63 volatile long timer1_toggle_count;
64 volatile uint8_t *timer1_pin_port;
65 volatile uint8_t timer1_pin_mask;
66 volatile long timer2_toggle_count;
67 volatile uint8_t *timer2_pin_port;
68 volatile uint8_t timer2_pin_mask;
69
70 #if defined(TIMSK3)
71 volatile long timer3_toggle_count;
72 volatile uint8_t *timer3_pin_port;
73 volatile uint8_t timer3_pin_mask;
74 #endif
75
76 #if defined(TIMSK4)
77 volatile long timer4_toggle_count;
78 volatile uint8_t *timer4_pin_port;
79 volatile uint8_t timer4_pin_mask;
80 #endif
81
82 #if defined(TIMSK5)
83 volatile long timer5_toggle_count;
84 volatile uint8_t *timer5_pin_port;
85 volatile uint8_t timer5_pin_mask;
86 #endif
87
88
89 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
90
91 #define AVAILABLE_TONE_PINS 1
92 #define USE_TIMER2
93
94 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
95 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
96
97 #elif defined(__AVR_ATmega8__)
98
99 #define AVAILABLE_TONE_PINS 1
100 #define USE_TIMER2
101
102 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
103 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
104
105 #elif defined(__AVR_ATmega32U4__)
106
107 #define AVAILABLE_TONE_PINS 1
108 #define USE_TIMER3
109
110 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };
111 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
112
113 #else
114
115 #define AVAILABLE_TONE_PINS 1
116 #define USE_TIMER2
117
118 // Leave timer 0 to last.
119 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
120 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
121
122 #endif
123
124
125
126 static int8_t toneBegin(uint8_t _pin)
127 {
128 int8_t _timer = -1;
129
130 // if we're already using the pin, the timer should be configured.
131 for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
132 if (tone_pins[i] == _pin) {
133 return pgm_read_byte(tone_pin_to_timer_PGM + i);
134 }
135 }
136
137 // search for an unused timer.
138 for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
139 if (tone_pins[i] == 255) {
140 tone_pins[i] = _pin;
141 _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
142 break;
143 }
144 }
145
146 if (_timer != -1)
147 {
148 // Set timer specific stuff
149 // All timers in CTC mode
150 // 8 bit timers will require changing prescalar values,
151 // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
152 switch (_timer)
153 {
154 #if defined(TCCR0A) && defined(TCCR0B)
155 case 0:
156 // 8 bit timer
157 TCCR0A = 0;
158 TCCR0B = 0;
159 bitWrite(TCCR0A, WGM01, 1);
160 bitWrite(TCCR0B, CS00, 1);
161 timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
162 timer0_pin_mask = digitalPinToBitMask(_pin);
163 break;
164 #endif
165
166 #if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
167 case 1:
168 // 16 bit timer
169 TCCR1A = 0;
170 TCCR1B = 0;
171 bitWrite(TCCR1B, WGM12, 1);
172 bitWrite(TCCR1B, CS10, 1);
173 timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
174 timer1_pin_mask = digitalPinToBitMask(_pin);
175 break;
176 #endif
177
178 #if defined(TCCR2A) && defined(TCCR2B)
179 case 2:
180 // 8 bit timer
181 TCCR2A = 0;
182 TCCR2B = 0;
183 bitWrite(TCCR2A, WGM21, 1);
184 bitWrite(TCCR2B, CS20, 1);
185 timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
186 timer2_pin_mask = digitalPinToBitMask(_pin);
187 break;
188 #endif
189
190 #if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3)
191 case 3:
192 // 16 bit timer
193 TCCR3A = 0;
194 TCCR3B = 0;
195 bitWrite(TCCR3B, WGM32, 1);
196 bitWrite(TCCR3B, CS30, 1);
197 timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
198 timer3_pin_mask = digitalPinToBitMask(_pin);
199 break;
200 #endif
201
202 #if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4)
203 case 4:
204 // 16 bit timer
205 TCCR4A = 0;
206 TCCR4B = 0;
207 #if defined(WGM42)
208 bitWrite(TCCR4B, WGM42, 1);
209 #elif defined(CS43)
210 #warning this may not be correct
211 // atmega32u4
212 bitWrite(TCCR4B, CS43, 1);
213 #endif
214 bitWrite(TCCR4B, CS40, 1);
215 timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
216 timer4_pin_mask = digitalPinToBitMask(_pin);
217 break;
218 #endif
219
220 #if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5)
221 case 5:
222 // 16 bit timer
223 TCCR5A = 0;
224 TCCR5B = 0;
225 bitWrite(TCCR5B, WGM52, 1);
226 bitWrite(TCCR5B, CS50, 1);
227 timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
228 timer5_pin_mask = digitalPinToBitMask(_pin);
229 break;
230 #endif
231 }
232 }
233
234 return _timer;
235 }
236
237
238
239 // frequency (in hertz) and duration (in milliseconds).
240
241 void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
242 {
243 uint8_t prescalarbits = 0b001;
244 long toggle_count = 0;
245 uint32_t ocr = 0;
246 int8_t _timer;
247
248 _timer = toneBegin(_pin);
249
250 if (_timer >= 0)
251 {
252 // Set the pinMode as OUTPUT
253 pinMode(_pin, OUTPUT);
254
255 // if we are using an 8 bit timer, scan through prescalars to find the best fit
256 if (_timer == 0 || _timer == 2)
257 {
258 ocr = F_CPU / frequency / 2 - 1;
259 prescalarbits = 0b001; // ck/1: same for both timers
260 if (ocr > 255)
261 {
262 ocr = F_CPU / frequency / 2 / 8 - 1;
263 prescalarbits = 0b010; // ck/8: same for both timers
264
265 if (_timer == 2 && ocr > 255)
266 {
267 ocr = F_CPU / frequency / 2 / 32 - 1;
268 prescalarbits = 0b011;
269 }
270
271 if (ocr > 255)
272 {
273 ocr = F_CPU / frequency / 2 / 64 - 1;
274 prescalarbits = _timer == 0 ? 0b011 : 0b100;
275
276 if (_timer == 2 && ocr > 255)
277 {
278 ocr = F_CPU / frequency / 2 / 128 - 1;
279 prescalarbits = 0b101;
280 }
281
282 if (ocr > 255)
283 {
284 ocr = F_CPU / frequency / 2 / 256 - 1;
285 prescalarbits = _timer == 0 ? 0b100 : 0b110;
286 if (ocr > 255)
287 {
288 // can't do any better than /1024
289 ocr = F_CPU / frequency / 2 / 1024 - 1;
290 prescalarbits = _timer == 0 ? 0b101 : 0b111;
291 }
292 }
293 }
294 }
295
296 #if defined(TCCR0B)
297 if (_timer == 0)
298 {
299 TCCR0B = prescalarbits;
300 }
301 else
302 #endif
303 #if defined(TCCR2B)
304 {
305 TCCR2B = prescalarbits;
306 }
307 #else
308 {
309 // dummy place holder to make the above ifdefs work
310 }
311 #endif
312 }
313 else
314 {
315 // two choices for the 16 bit timers: ck/1 or ck/64
316 ocr = F_CPU / frequency / 2 - 1;
317
318 prescalarbits = 0b001;
319 if (ocr > 0xffff)
320 {
321 ocr = F_CPU / frequency / 2 / 64 - 1;
322 prescalarbits = 0b011;
323 }
324
325 if (_timer == 1)
326 {
327 #if defined(TCCR1B)
328 TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
329 #endif
330 }
331 #if defined(TCCR3B)
332 else if (_timer == 3)
333 TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
334 #endif
335 #if defined(TCCR4B)
336 else if (_timer == 4)
337 TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
338 #endif
339 #if defined(TCCR5B)
340 else if (_timer == 5)
341 TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
342 #endif
343
344 }
345
346
347 // Calculate the toggle count
348 if (duration > 0)
349 {
350 toggle_count = 2 * frequency * duration / 1000;
351 }
352 else
353 {
354 toggle_count = -1;
355 }
356
357 // Set the OCR for the given timer,
358 // set the toggle count,
359 // then turn on the interrupts
360 switch (_timer)
361 {
362
363 #if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A)
364 case 0:
365 OCR0A = ocr;
366 timer0_toggle_count = toggle_count;
367 bitWrite(TIMSK0, OCIE0A, 1);
368 break;
369 #endif
370
371 case 1:
372 #if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A)
373 OCR1A = ocr;
374 timer1_toggle_count = toggle_count;
375 bitWrite(TIMSK1, OCIE1A, 1);
376 #elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A)
377 // this combination is for at least the ATmega32
378 OCR1A = ocr;
379 timer1_toggle_count = toggle_count;
380 bitWrite(TIMSK, OCIE1A, 1);
381 #endif
382 break;
383
384 #if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A)
385 case 2:
386 OCR2A = ocr;
387 timer2_toggle_count = toggle_count;
388 bitWrite(TIMSK2, OCIE2A, 1);
389 break;
390 #endif
391
392 #if defined(TIMSK3)
393 case 3:
394 OCR3A = ocr;
395 timer3_toggle_count = toggle_count;
396 bitWrite(TIMSK3, OCIE3A, 1);
397 break;
398 #endif
399
400 #if defined(TIMSK4)
401 case 4:
402 OCR4A = ocr;
403 timer4_toggle_count = toggle_count;
404 bitWrite(TIMSK4, OCIE4A, 1);
405 break;
406 #endif
407
408 #if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A)
409 case 5:
410 OCR5A = ocr;
411 timer5_toggle_count = toggle_count;
412 bitWrite(TIMSK5, OCIE5A, 1);
413 break;
414 #endif
415
416 }
417 }
418 }
419
420
421 // XXX: this function only works properly for timer 2 (the only one we use
422 // currently). for the others, it should end the tone, but won't restore
423 // proper PWM functionality for the timer.
424 void disableTimer(uint8_t _timer)
425 {
426 switch (_timer)
427 {
428 case 0:
429 #if defined(TIMSK0)
430 TIMSK0 = 0;
431 #elif defined(TIMSK)
432 TIMSK = 0; // atmega32
433 #endif
434 break;
435
436 #if defined(TIMSK1) && defined(OCIE1A)
437 case 1:
438 bitWrite(TIMSK1, OCIE1A, 0);
439 break;
440 #endif
441
442 case 2:
443 #if defined(TIMSK2) && defined(OCIE2A)
444 bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
445 #endif
446 #if defined(TCCR2A) && defined(WGM20)
447 TCCR2A = (1 << WGM20);
448 #endif
449 #if defined(TCCR2B) && defined(CS22)
450 TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
451 #endif
452 #if defined(OCR2A)
453 OCR2A = 0;
454 #endif
455 break;
456
457 #if defined(TIMSK3)
458 case 3:
459 TIMSK3 = 0;
460 break;
461 #endif
462
463 #if defined(TIMSK4)
464 case 4:
465 TIMSK4 = 0;
466 break;
467 #endif
468
469 #if defined(TIMSK5)
470 case 5:
471 TIMSK5 = 0;
472 break;
473 #endif
474 }
475 }
476
477
478 void noTone(uint8_t _pin)
479 {
480 int8_t _timer = -1;
481
482 for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
483 if (tone_pins[i] == _pin) {
484 _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
485 tone_pins[i] = 255;
486 }
487 }
488
489 disableTimer(_timer);
490
491 digitalWrite(_pin, 0);
492 }
493
494 #ifdef USE_TIMER0
495 ISR(TIMER0_COMPA_vect)
496 {
497 if (timer0_toggle_count != 0)
498 {
499 // toggle the pin
500 *timer0_pin_port ^= timer0_pin_mask;
501
502 if (timer0_toggle_count > 0)
503 timer0_toggle_count--;
504 }
505 else
506 {
507 disableTimer(0);
508 *timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop
509 }
510 }
511 #endif
512
513
514 #ifdef USE_TIMER1
515 ISR(TIMER1_COMPA_vect)
516 {
517 if (timer1_toggle_count != 0)
518 {
519 // toggle the pin
520 *timer1_pin_port ^= timer1_pin_mask;
521
522 if (timer1_toggle_count > 0)
523 timer1_toggle_count--;
524 }
525 else
526 {
527 disableTimer(1);
528 *timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop
529 }
530 }
531 #endif
532
533
534 #ifdef USE_TIMER2
535 ISR(TIMER2_COMPA_vect)
536 {
537
538 if (timer2_toggle_count != 0)
539 {
540 // toggle the pin
541 *timer2_pin_port ^= timer2_pin_mask;
542
543 if (timer2_toggle_count > 0)
544 timer2_toggle_count--;
545 }
546 else
547 {
548 // need to call noTone() so that the tone_pins[] entry is reset, so the
549 // timer gets initialized next time we call tone().
550 // XXX: this assumes timer 2 is always the first one used.
551 noTone(tone_pins[0]);
552 // disableTimer(2);
553 // *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
554 }
555 }
556 #endif
557
558
559 #ifdef USE_TIMER3
560 ISR(TIMER3_COMPA_vect)
561 {
562 if (timer3_toggle_count != 0)
563 {
564 // toggle the pin
565 *timer3_pin_port ^= timer3_pin_mask;
566
567 if (timer3_toggle_count > 0)
568 timer3_toggle_count--;
569 }
570 else
571 {
572 disableTimer(3);
573 *timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop
574 }
575 }
576 #endif
577
578
579 #ifdef USE_TIMER4
580 ISR(TIMER4_COMPA_vect)
581 {
582 if (timer4_toggle_count != 0)
583 {
584 // toggle the pin
585 *timer4_pin_port ^= timer4_pin_mask;
586
587 if (timer4_toggle_count > 0)
588 timer4_toggle_count--;
589 }
590 else
591 {
592 disableTimer(4);
593 *timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop
594 }
595 }
596 #endif
597
598
599 #ifdef USE_TIMER5
600 ISR(TIMER5_COMPA_vect)
601 {
602 if (timer5_toggle_count != 0)
603 {
604 // toggle the pin
605 *timer5_pin_port ^= timer5_pin_mask;
606
607 if (timer5_toggle_count > 0)
608 timer5_toggle_count--;
609 }
610 else
611 {
612 disableTimer(5);
613 *timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop
614 }
615 }
616 #endif
@@ -0,0 +1,198
1
2
3 #ifndef __USBAPI__
4 #define __USBAPI__
5
6 #if defined(USBCON)
7
8 //================================================================================
9 //================================================================================
10 // USB
11
12 class USBDevice_
13 {
14 public:
15 USBDevice_();
16 bool configured();
17
18 void attach();
19 void detach(); // Serial port goes down too...
20 void poll();
21 };
22 extern USBDevice_ USBDevice;
23
24 //================================================================================
25 //================================================================================
26 // Serial over CDC (Serial1 is the physical port)
27
28 class Serial_ : public Stream
29 {
30 private:
31 int peek_buffer;
32 public:
33 Serial_() { peek_buffer = -1; };
34 void begin(unsigned long);
35 void begin(unsigned long, uint8_t);
36 void end(void);
37
38 virtual int available(void);
39 virtual int peek(void);
40 virtual int read(void);
41 virtual void flush(void);
42 virtual size_t write(uint8_t);
43 virtual size_t write(const uint8_t*, size_t);
44 using Print::write; // pull in write(str) and write(buf, size) from Print
45 operator bool();
46 };
47 extern Serial_ Serial;
48
49 //================================================================================
50 //================================================================================
51 // Mouse
52
53 #define MOUSE_LEFT 1
54 #define MOUSE_RIGHT 2
55 #define MOUSE_MIDDLE 4
56 #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
57
58 class Mouse_
59 {
60 private:
61 uint8_t _buttons;
62 void buttons(uint8_t b);
63 public:
64 Mouse_(void);
65 void begin(void);
66 void end(void);
67 void click(uint8_t b = MOUSE_LEFT);
68 void move(signed char x, signed char y, signed char wheel = 0);
69 void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
70 void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
71 bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
72 };
73 extern Mouse_ Mouse;
74
75 //================================================================================
76 //================================================================================
77 // Keyboard
78
79 #define KEY_LEFT_CTRL 0x80
80 #define KEY_LEFT_SHIFT 0x81
81 #define KEY_LEFT_ALT 0x82
82 #define KEY_LEFT_GUI 0x83
83 #define KEY_RIGHT_CTRL 0x84
84 #define KEY_RIGHT_SHIFT 0x85
85 #define KEY_RIGHT_ALT 0x86
86 #define KEY_RIGHT_GUI 0x87
87
88 #define KEY_UP_ARROW 0xDA
89 #define KEY_DOWN_ARROW 0xD9
90 #define KEY_LEFT_ARROW 0xD8
91 #define KEY_RIGHT_ARROW 0xD7
92 #define KEY_BACKSPACE 0xB2
93 #define KEY_TAB 0xB3
94 #define KEY_RETURN 0xB0
95 #define KEY_ESC 0xB1
96 #define KEY_INSERT 0xD1
97 #define KEY_DELETE 0xD4
98 #define KEY_PAGE_UP 0xD3
99 #define KEY_PAGE_DOWN 0xD6
100 #define KEY_HOME 0xD2
101 #define KEY_END 0xD5
102 #define KEY_CAPS_LOCK 0xC1
103 #define KEY_F1 0xC2
104 #define KEY_F2 0xC3
105 #define KEY_F3 0xC4
106 #define KEY_F4 0xC5
107 #define KEY_F5 0xC6
108 #define KEY_F6 0xC7
109 #define KEY_F7 0xC8
110 #define KEY_F8 0xC9
111 #define KEY_F9 0xCA
112 #define KEY_F10 0xCB
113 #define KEY_F11 0xCC
114 #define KEY_F12 0xCD
115
116 // Low level key report: up to 6 keys and shift, ctrl etc at once
117 typedef struct
118 {
119 uint8_t modifiers;
120 uint8_t reserved;
121 uint8_t keys[6];
122 } KeyReport;
123
124 class Keyboard_ : public Print
125 {
126 private:
127 KeyReport _keyReport;
128 void sendReport(KeyReport* keys);
129 public:
130 Keyboard_(void);
131 void begin(void);
132 void end(void);
133 virtual size_t write(uint8_t k);
134 virtual size_t press(uint8_t k);
135 virtual size_t release(uint8_t k);
136 virtual void releaseAll(void);
137 };
138 extern Keyboard_ Keyboard;
139
140 //================================================================================
141 //================================================================================
142 // Low level API
143
144 typedef struct
145 {
146 uint8_t bmRequestType;
147 uint8_t bRequest;
148 uint8_t wValueL;
149 uint8_t wValueH;
150 uint16_t wIndex;
151 uint16_t wLength;
152 } Setup;
153
154 //================================================================================
155 //================================================================================
156 // HID 'Driver'
157
158 int HID_GetInterface(uint8_t* interfaceNum);
159 int HID_GetDescriptor(int i);
160 bool HID_Setup(Setup& setup);
161 void HID_SendReport(uint8_t id, const void* data, int len);
162
163 //================================================================================
164 //================================================================================
165 // MSC 'Driver'
166
167 int MSC_GetInterface(uint8_t* interfaceNum);
168 int MSC_GetDescriptor(int i);
169 bool MSC_Setup(Setup& setup);
170 bool MSC_Data(uint8_t rx,uint8_t tx);
171
172 //================================================================================
173 //================================================================================
174 // CSC 'Driver'
175
176 int CDC_GetInterface(uint8_t* interfaceNum);
177 int CDC_GetDescriptor(int i);
178 bool CDC_Setup(Setup& setup);
179
180 //================================================================================
181 //================================================================================
182
183 #define TRANSFER_PGM 0x80
184 #define TRANSFER_RELEASE 0x40
185 #define TRANSFER_ZERO 0x20
186
187 int USB_SendControl(uint8_t flags, const void* d, int len);
188 int USB_RecvControl(void* d, int len);
189
190 uint8_t USB_Available(uint8_t ep);
191 int USB_Send(uint8_t ep, const void* data, int len); // blocking
192 int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
193 int USB_Recv(uint8_t ep); // non-blocking
194 void USB_Flush(uint8_t ep);
195
196 #endif
197
198 #endif /* if defined(USBCON) */
This diff has been collapsed as it changes many lines, (685 lines changed) Show them Hide them
@@ -0,0 +1,685
1
2
3 /* Copyright (c) 2010, Peter Barrett
4 **
5 ** Permission to use, copy, modify, and/or distribute this software for
6 ** any purpose with or without fee is hereby granted, provided that the
7 ** above copyright notice and this permission notice appear in all copies.
8 **
9 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
12 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
13 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
14 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 ** SOFTWARE.
17 */
18
19 #include "Platform.h"
20 #include "USBAPI.h"
21 #include "USBDesc.h"
22
23 #if defined(USBCON)
24
25 #define EP_TYPE_CONTROL 0x00
26 #define EP_TYPE_BULK_IN 0x81
27 #define EP_TYPE_BULK_OUT 0x80
28 #define EP_TYPE_INTERRUPT_IN 0xC1
29 #define EP_TYPE_INTERRUPT_OUT 0xC0
30 #define EP_TYPE_ISOCHRONOUS_IN 0x41
31 #define EP_TYPE_ISOCHRONOUS_OUT 0x40
32
33 /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
34 #define TX_RX_LED_PULSE_MS 100
35 volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
36 volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
37
38 //==================================================================
39 //==================================================================
40
41 extern const u16 STRING_LANGUAGE[] PROGMEM;
42 extern const u16 STRING_IPRODUCT[] PROGMEM;
43 extern const u16 STRING_IMANUFACTURER[] PROGMEM;
44 extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM;
45 extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM;
46
47 const u16 STRING_LANGUAGE[2] = {
48 (3<<8) | (2+2),
49 0x0409 // English
50 };
51
52 const u16 STRING_IPRODUCT[17] = {
53 (3<<8) | (2+2*16),
54 #if USB_PID == 0x8036
55 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o'
56 #elif USB_PID == 0x8037
57 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' '
58 #elif USB_PID == 0x803C
59 'A','r','d','u','i','n','o',' ','E','s','p','l','o','r','a',' '
60 #elif USB_PID == 0x9208
61 'L','i','l','y','P','a','d','U','S','B',' ',' ',' ',' ',' ',' '
62 #else
63 'U','S','B',' ','I','O',' ','B','o','a','r','d',' ',' ',' ',' '
64 #endif
65 };
66
67 const u16 STRING_IMANUFACTURER[12] = {
68 (3<<8) | (2+2*11),
69 #if USB_VID == 0x2341
70 'A','r','d','u','i','n','o',' ','L','L','C'
71 #elif USB_VID == 0x1b4f
72 'S','p','a','r','k','F','u','n',' ',' ',' '
73 #else
74 'U','n','k','n','o','w','n',' ',' ',' ',' '
75 #endif
76 };
77
78 #ifdef CDC_ENABLED
79 #define DEVICE_CLASS 0x02
80 #else
81 #define DEVICE_CLASS 0x00
82 #endif
83
84 // DEVICE DESCRIPTOR
85 const DeviceDescriptor USB_DeviceDescriptor =
86 D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
87
88 const DeviceDescriptor USB_DeviceDescriptorA =
89 D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
90
91 //==================================================================
92 //==================================================================
93
94 volatile u8 _usbConfiguration = 0;
95
96 static inline void WaitIN(void)
97 {
98 while (!(UEINTX & (1<<TXINI)));
99 }
100
101 static inline void ClearIN(void)
102 {
103 UEINTX = ~(1<<TXINI);
104 }
105
106 static inline void WaitOUT(void)
107 {
108 while (!(UEINTX & (1<<RXOUTI)))
109 ;
110 }
111
112 static inline u8 WaitForINOrOUT()
113 {
114 while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI))))
115 ;
116 return (UEINTX & (1<<RXOUTI)) == 0;
117 }
118
119 static inline void ClearOUT(void)
120 {
121 UEINTX = ~(1<<RXOUTI);
122 }
123
124 void Recv(volatile u8* data, u8 count)
125 {
126 while (count--)
127 *data++ = UEDATX;
128
129 RXLED1; // light the RX LED
130 RxLEDPulse = TX_RX_LED_PULSE_MS;
131 }
132
133 static inline u8 Recv8()
134 {
135 RXLED1; // light the RX LED
136 RxLEDPulse = TX_RX_LED_PULSE_MS;
137
138 return UEDATX;
139 }
140
141 static inline void Send8(u8 d)
142 {
143 UEDATX = d;
144 }
145
146 static inline void SetEP(u8 ep)
147 {
148 UENUM = ep;
149 }
150
151 static inline u8 FifoByteCount()
152 {
153 return UEBCLX;
154 }
155
156 static inline u8 ReceivedSetupInt()
157 {
158 return UEINTX & (1<<RXSTPI);
159 }
160
161 static inline void ClearSetupInt()
162 {
163 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
164 }
165
166 static inline void Stall()
167 {
168 UECONX = (1<<STALLRQ) | (1<<EPEN);
169 }
170
171 static inline u8 ReadWriteAllowed()
172 {
173 return UEINTX & (1<<RWAL);
174 }
175
176 static inline u8 Stalled()
177 {
178 return UEINTX & (1<<STALLEDI);
179 }
180
181 static inline u8 FifoFree()
182 {
183 return UEINTX & (1<<FIFOCON);
184 }
185
186 static inline void ReleaseRX()
187 {
188 UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1
189 }
190
191 static inline void ReleaseTX()
192 {
193 UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0
194 }
195
196 static inline u8 FrameNumber()
197 {
198 return UDFNUML;
199 }
200
201 //==================================================================
202 //==================================================================
203
204 u8 USBGetConfiguration(void)
205 {
206 return _usbConfiguration;
207 }
208
209 #define USB_RECV_TIMEOUT
210 class LockEP
211 {
212 u8 _sreg;
213 public:
214 LockEP(u8 ep) : _sreg(SREG)
215 {
216 cli();
217 SetEP(ep & 7);
218 }
219 ~LockEP()
220 {
221 SREG = _sreg;
222 }
223 };
224
225 // Number of bytes, assumes a rx endpoint
226 u8 USB_Available(u8 ep)
227 {
228 LockEP lock(ep);
229 return FifoByteCount();
230 }
231
232 // Non Blocking receive
233 // Return number of bytes read
234 int USB_Recv(u8 ep, void* d, int len)
235 {
236 if (!_usbConfiguration || len < 0)
237 return -1;
238
239 LockEP lock(ep);
240 u8 n = FifoByteCount();
241 len = min(n,len);
242 n = len;
243 u8* dst = (u8*)d;
244 while (n--)
245 *dst++ = Recv8();
246 if (len && !FifoByteCount()) // release empty buffer
247 ReleaseRX();
248
249 return len;
250 }
251
252 // Recv 1 byte if ready
253 int USB_Recv(u8 ep)
254 {
255 u8 c;
256 if (USB_Recv(ep,&c,1) != 1)
257 return -1;
258 return c;
259 }
260
261 // Space in send EP
262 u8 USB_SendSpace(u8 ep)
263 {
264 LockEP lock(ep);
265 if (!ReadWriteAllowed())
266 return 0;
267 return 64 - FifoByteCount();
268 }
269
270 // Blocking Send of data to an endpoint
271 int USB_Send(u8 ep, const void* d, int len)
272 {
273 if (!_usbConfiguration)
274 return -1;
275
276 int r = len;
277 const u8* data = (const u8*)d;
278 u8 zero = ep & TRANSFER_ZERO;
279 u8 timeout = 250; // 250ms timeout on send? TODO
280 while (len)
281 {
282 u8 n = USB_SendSpace(ep);
283 if (n == 0)
284 {
285 if (!(--timeout))
286 return -1;
287 delay(1);
288 continue;
289 }
290
291 if (n > len)
292 n = len;
293 {
294 LockEP lock(ep);
295 // Frame may have been released by the SOF interrupt handler
296 if (!ReadWriteAllowed())
297 continue;
298 len -= n;
299 if (ep & TRANSFER_ZERO)
300 {
301 while (n--)
302 Send8(0);
303 }
304 else if (ep & TRANSFER_PGM)
305 {
306 while (n--)
307 Send8(pgm_read_byte(data++));
308 }
309 else
310 {
311 while (n--)
312 Send8(*data++);
313 }
314 if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer
315 ReleaseTX();
316 }
317 }
318 TXLED1; // light the TX LED
319 TxLEDPulse = TX_RX_LED_PULSE_MS;
320 return r;
321 }
322
323 extern const u8 _initEndpoints[] PROGMEM;
324 const u8 _initEndpoints[] =
325 {
326 0,
327
328 #ifdef CDC_ENABLED
329 EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
330 EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
331 EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
332 #endif
333
334 #ifdef HID_ENABLED
335 EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT
336 #endif
337 };
338
339 #define EP_SINGLE_64 0x32 // EP0
340 #define EP_DOUBLE_64 0x36 // Other endpoints
341
342 static
343 void InitEP(u8 index, u8 type, u8 size)
344 {
345 UENUM = index;
346 UECONX = 1;
347 UECFG0X = type;
348 UECFG1X = size;
349 }
350
351 static
352 void InitEndpoints()
353 {
354 for (u8 i = 1; i < sizeof(_initEndpoints); i++)
355 {
356 UENUM = i;
357 UECONX = 1;
358 UECFG0X = pgm_read_byte(_initEndpoints+i);
359 UECFG1X = EP_DOUBLE_64;
360 }
361 UERST = 0x7E; // And reset them
362 UERST = 0;
363 }
364
365 // Handle CLASS_INTERFACE requests
366 static
367 bool ClassInterfaceRequest(Setup& setup)
368 {
369 u8 i = setup.wIndex;
370
371 #ifdef CDC_ENABLED
372 if (CDC_ACM_INTERFACE == i)
373 return CDC_Setup(setup);
374 #endif
375
376 #ifdef HID_ENABLED
377 if (HID_INTERFACE == i)
378 return HID_Setup(setup);
379 #endif
380 return false;
381 }
382
383 int _cmark;
384 int _cend;
385 void InitControl(int end)
386 {
387 SetEP(0);
388 _cmark = 0;
389 _cend = end;
390 }
391
392 static
393 bool SendControl(u8 d)
394 {
395 if (_cmark < _cend)
396 {
397 if (!WaitForINOrOUT())
398 return false;
399 Send8(d);
400 if (!((_cmark + 1) & 0x3F))
401 ClearIN(); // Fifo is full, release this packet
402 }
403 _cmark++;
404 return true;
405 };
406
407 // Clipped by _cmark/_cend
408 int USB_SendControl(u8 flags, const void* d, int len)
409 {
410 int sent = len;
411 const u8* data = (const u8*)d;
412 bool pgm = flags & TRANSFER_PGM;
413 while (len--)
414 {
415 u8 c = pgm ? pgm_read_byte(data++) : *data++;
416 if (!SendControl(c))
417 return -1;
418 }
419 return sent;
420 }
421
422 // Does not timeout or cross fifo boundaries
423 // Will only work for transfers <= 64 bytes
424 // TODO
425 int USB_RecvControl(void* d, int len)
426 {
427 WaitOUT();
428 Recv((u8*)d,len);
429 ClearOUT();
430 return len;
431 }
432
433 int SendInterfaces()
434 {
435 int total = 0;
436 u8 interfaces = 0;
437
438 #ifdef CDC_ENABLED
439 total = CDC_GetInterface(&interfaces);
440 #endif
441
442 #ifdef HID_ENABLED
443 total += HID_GetInterface(&interfaces);
444 #endif
445
446 return interfaces;
447 }
448
449 // Construct a dynamic configuration descriptor
450 // This really needs dynamic endpoint allocation etc
451 // TODO
452 static
453 bool SendConfiguration(int maxlen)
454 {
455 // Count and measure interfaces
456 InitControl(0);
457 int interfaces = SendInterfaces();
458 ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
459
460 // Now send them
461 InitControl(maxlen);
462 USB_SendControl(0,&config,sizeof(ConfigDescriptor));
463 SendInterfaces();
464 return true;
465 }
466
467 u8 _cdcComposite = 0;
468
469 static
470 bool SendDescriptor(Setup& setup)
471 {
472 u8 t = setup.wValueH;
473 if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
474 return SendConfiguration(setup.wLength);
475
476 InitControl(setup.wLength);
477 #ifdef HID_ENABLED
478 if (HID_REPORT_DESCRIPTOR_TYPE == t)
479 return HID_GetDescriptor(t);
480 #endif
481
482 u8 desc_length = 0;
483 const u8* desc_addr = 0;
484 if (USB_DEVICE_DESCRIPTOR_TYPE == t)
485 {
486 if (setup.wLength == 8)
487 _cdcComposite = 1;
488 desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor;
489 }
490 else if (USB_STRING_DESCRIPTOR_TYPE == t)
491 {
492 if (setup.wValueL == 0)
493 desc_addr = (const u8*)&STRING_LANGUAGE;
494 else if (setup.wValueL == IPRODUCT)
495 desc_addr = (const u8*)&STRING_IPRODUCT;
496 else if (setup.wValueL == IMANUFACTURER)
497 desc_addr = (const u8*)&STRING_IMANUFACTURER;
498 else
499 return false;
500 }
501
502 if (desc_addr == 0)
503 return false;
504 if (desc_length == 0)
505 desc_length = pgm_read_byte(desc_addr);
506
507 USB_SendControl(TRANSFER_PGM,desc_addr,desc_length);
508 return true;
509 }
510
511 // Endpoint 0 interrupt
512 ISR(USB_COM_vect)
513 {
514 SetEP(0);
515 if (!ReceivedSetupInt())
516 return;
517
518 Setup setup;
519 Recv((u8*)&setup,8);
520 ClearSetupInt();
521
522 u8 requestType = setup.bmRequestType;
523 if (requestType & REQUEST_DEVICETOHOST)
524 WaitIN();
525 else
526 ClearIN();
527
528 bool ok = true;
529 if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
530 {
531 // Standard Requests
532 u8 r = setup.bRequest;
533 if (GET_STATUS == r)
534 {
535 Send8(0); // TODO
536 Send8(0);
537 }
538 else if (CLEAR_FEATURE == r)
539 {
540 }
541 else if (SET_FEATURE == r)
542 {
543 }
544 else if (SET_ADDRESS == r)
545 {
546 WaitIN();
547 UDADDR = setup.wValueL | (1<<ADDEN);
548 }
549 else if (GET_DESCRIPTOR == r)
550 {
551 ok = SendDescriptor(setup);
552 }
553 else if (SET_DESCRIPTOR == r)
554 {
555 ok = false;
556 }
557 else if (GET_CONFIGURATION == r)
558 {
559 Send8(1);
560 }
561 else if (SET_CONFIGURATION == r)
562 {
563 if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
564 {
565 InitEndpoints();
566 _usbConfiguration = setup.wValueL;
567 } else
568 ok = false;
569 }
570 else if (GET_INTERFACE == r)
571 {
572 }
573 else if (SET_INTERFACE == r)
574 {
575 }
576 }
577 else
578 {
579 InitControl(setup.wLength); // Max length of transfer
580 ok = ClassInterfaceRequest(setup);
581 }
582
583 if (ok)
584 ClearIN();
585 else
586 {
587 Stall();
588 }
589 }
590
591 void USB_Flush(u8 ep)
592 {
593 SetEP(ep);
594 if (FifoByteCount())
595 ReleaseTX();
596 }
597
598 // General interrupt
599 ISR(USB_GEN_vect)
600 {
601 u8 udint = UDINT;
602 UDINT = 0;
603
604 // End of Reset
605 if (udint & (1<<EORSTI))
606 {
607 InitEP(0,EP_TYPE_CONTROL,EP_SINGLE_64); // init ep0
608 _usbConfiguration = 0; // not configured yet
609 UEIENX = 1 << RXSTPE; // Enable interrupts for ep0
610 }
611
612 // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
613 if (udint & (1<<SOFI))
614 {
615 #ifdef CDC_ENABLED
616 USB_Flush(CDC_TX); // Send a tx frame if found
617 #endif
618
619 // check whether the one-shot period has elapsed. if so, turn off the LED
620 if (TxLEDPulse && !(--TxLEDPulse))
621 TXLED0;
622 if (RxLEDPulse && !(--RxLEDPulse))
623 RXLED0;
624 }
625 }
626
627 // VBUS or counting frames
628 // Any frame counting?
629 u8 USBConnected()
630 {
631 u8 f = UDFNUML;
632 delay(3);
633 return f != UDFNUML;
634 }
635
636 //=======================================================================
637 //=======================================================================
638
639 USBDevice_ USBDevice;
640
641 USBDevice_::USBDevice_()
642 {
643 }
644
645 void USBDevice_::attach()
646 {
647 _usbConfiguration = 0;
648 UHWCON = 0x01; // power internal reg
649 USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled
650 #if F_CPU == 16000000UL
651 PLLCSR = 0x12; // Need 16 MHz xtal
652 #elif F_CPU == 8000000UL
653 PLLCSR = 0x02; // Need 8 MHz xtal
654 #endif
655 while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll
656 ;
657
658 // Some tests on specific versions of macosx (10.7.3), reported some
659 // strange behaviuors when the board is reset using the serial
660 // port touch at 1200 bps. This delay fixes this behaviour.
661 delay(1);
662
663 USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock
664 UDIEN = (1<<EORSTE)|(1<<SOFE); // Enable interrupts for EOR (End of Reset) and SOF (start of frame)
665 UDCON = 0; // enable attach resistor
666
667 TX_RX_LED_INIT;
668 }
669
670 void USBDevice_::detach()
671 {
672 }
673
674 // Check for interrupts
675 // TODO: VBUS detection
676 bool USBDevice_::configured()
677 {
678 return _usbConfiguration;
679 }
680
681 void USBDevice_::poll()
682 {
683 }
684
685 #endif /* if defined(USBCON) */
@@ -0,0 +1,303
1
2 // Copyright (c) 2010, Peter Barrett
3 /*
4 ** Permission to use, copy, modify, and/or distribute this software for
5 ** any purpose with or without fee is hereby granted, provided that the
6 ** above copyright notice and this permission notice appear in all copies.
7 **
8 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
11 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
12 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
13 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
14 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15 ** SOFTWARE.
16 */
17
18 #ifndef __USBCORE_H__
19 #define __USBCORE_H__
20
21 // Standard requests
22 #define GET_STATUS 0
23 #define CLEAR_FEATURE 1
24 #define SET_FEATURE 3
25 #define SET_ADDRESS 5
26 #define GET_DESCRIPTOR 6
27 #define SET_DESCRIPTOR 7
28 #define GET_CONFIGURATION 8
29 #define SET_CONFIGURATION 9
30 #define GET_INTERFACE 10
31 #define SET_INTERFACE 11
32
33
34 // bmRequestType
35 #define REQUEST_HOSTTODEVICE 0x00
36 #define REQUEST_DEVICETOHOST 0x80
37 #define REQUEST_DIRECTION 0x80
38
39 #define REQUEST_STANDARD 0x00
40 #define REQUEST_CLASS 0x20
41 #define REQUEST_VENDOR 0x40
42 #define REQUEST_TYPE 0x60
43
44 #define REQUEST_DEVICE 0x00
45 #define REQUEST_INTERFACE 0x01
46 #define REQUEST_ENDPOINT 0x02
47 #define REQUEST_OTHER 0x03
48 #define REQUEST_RECIPIENT 0x03
49
50 #define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE)
51 #define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE)
52
53 // Class requests
54
55 #define CDC_SET_LINE_CODING 0x20
56 #define CDC_GET_LINE_CODING 0x21
57 #define CDC_SET_CONTROL_LINE_STATE 0x22
58
59 #define MSC_RESET 0xFF
60 #define MSC_GET_MAX_LUN 0xFE
61
62 #define HID_GET_REPORT 0x01
63 #define HID_GET_IDLE 0x02
64 #define HID_GET_PROTOCOL 0x03
65 #define HID_SET_REPORT 0x09
66 #define HID_SET_IDLE 0x0A
67 #define HID_SET_PROTOCOL 0x0B
68
69 // Descriptors
70
71 #define USB_DEVICE_DESC_SIZE 18
72 #define USB_CONFIGUARTION_DESC_SIZE 9
73 #define USB_INTERFACE_DESC_SIZE 9
74 #define USB_ENDPOINT_DESC_SIZE 7
75
76 #define USB_DEVICE_DESCRIPTOR_TYPE 1
77 #define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
78 #define USB_STRING_DESCRIPTOR_TYPE 3
79 #define USB_INTERFACE_DESCRIPTOR_TYPE 4
80 #define USB_ENDPOINT_DESCRIPTOR_TYPE 5
81
82 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
83 #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
84 #define USB_DEVICE_CLASS_STORAGE 0x08
85 #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
86
87 #define USB_CONFIG_POWERED_MASK 0x40
88 #define USB_CONFIG_BUS_POWERED 0x80
89 #define USB_CONFIG_SELF_POWERED 0xC0
90 #define USB_CONFIG_REMOTE_WAKEUP 0x20
91
92 // bMaxPower in Configuration Descriptor
93 #define USB_CONFIG_POWER_MA(mA) ((mA)/2)
94
95 // bEndpointAddress in Endpoint Descriptor
96 #define USB_ENDPOINT_DIRECTION_MASK 0x80
97 #define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
98 #define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
99
100 #define USB_ENDPOINT_TYPE_MASK 0x03
101 #define USB_ENDPOINT_TYPE_CONTROL 0x00
102 #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
103 #define USB_ENDPOINT_TYPE_BULK 0x02
104 #define USB_ENDPOINT_TYPE_INTERRUPT 0x03
105
106 #define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
107
108 #define CDC_V1_10 0x0110
109 #define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
110
111 #define CDC_CALL_MANAGEMENT 0x01
112 #define CDC_ABSTRACT_CONTROL_MODEL 0x02
113 #define CDC_HEADER 0x00
114 #define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
115 #define CDC_UNION 0x06
116 #define CDC_CS_INTERFACE 0x24
117 #define CDC_CS_ENDPOINT 0x25
118 #define CDC_DATA_INTERFACE_CLASS 0x0A
119
120 #define MSC_SUBCLASS_SCSI 0x06
121 #define MSC_PROTOCOL_BULK_ONLY 0x50
122
123 #define HID_HID_DESCRIPTOR_TYPE 0x21
124 #define HID_REPORT_DESCRIPTOR_TYPE 0x22
125 #define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
126
127
128 // Device
129 typedef struct {
130 u8 len; // 18
131 u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
132 u16 usbVersion; // 0x200
133 u8 deviceClass;
134 u8 deviceSubClass;
135 u8 deviceProtocol;
136 u8 packetSize0; // Packet 0
137 u16 idVendor;
138 u16 idProduct;
139 u16 deviceVersion; // 0x100
140 u8 iManufacturer;
141 u8 iProduct;
142 u8 iSerialNumber;
143 u8 bNumConfigurations;
144 } DeviceDescriptor;
145
146 // Config
147 typedef struct {
148 u8 len; // 9
149 u8 dtype; // 2
150 u16 clen; // total length
151 u8 numInterfaces;
152 u8 config;
153 u8 iconfig;
154 u8 attributes;
155 u8 maxPower;
156 } ConfigDescriptor;
157
158 // String
159
160 // Interface
161 typedef struct
162 {
163 u8 len; // 9
164 u8 dtype; // 4
165 u8 number;
166 u8 alternate;
167 u8 numEndpoints;
168 u8 interfaceClass;
169 u8 interfaceSubClass;
170 u8 protocol;
171 u8 iInterface;
172 } InterfaceDescriptor;
173
174 // Endpoint
175 typedef struct
176 {
177 u8 len; // 7
178 u8 dtype; // 5
179 u8 addr;
180 u8 attr;
181 u16 packetSize;
182 u8 interval;
183 } EndpointDescriptor;
184
185 // Interface Association Descriptor
186 // Used to bind 2 interfaces together in CDC compostite device
187 typedef struct
188 {
189 u8 len; // 8
190 u8 dtype; // 11
191 u8 firstInterface;
192 u8 interfaceCount;
193 u8 functionClass;
194 u8 funtionSubClass;
195 u8 functionProtocol;
196 u8 iInterface;
197 } IADDescriptor;
198
199 // CDC CS interface descriptor
200 typedef struct
201 {
202 u8 len; // 5
203 u8 dtype; // 0x24
204 u8 subtype;
205 u8 d0;
206 u8 d1;
207 } CDCCSInterfaceDescriptor;
208
209 typedef struct
210 {
211 u8 len; // 4
212 u8 dtype; // 0x24
213 u8 subtype;
214 u8 d0;
215 } CDCCSInterfaceDescriptor4;
216
217 typedef struct
218 {
219 u8 len;
220 u8 dtype; // 0x24
221 u8 subtype; // 1
222 u8 bmCapabilities;
223 u8 bDataInterface;
224 } CMFunctionalDescriptor;
225
226 typedef struct
227 {
228 u8 len;
229 u8 dtype; // 0x24
230 u8 subtype; // 1
231 u8 bmCapabilities;
232 } ACMFunctionalDescriptor;
233
234 typedef struct
235 {
236 // IAD
237 IADDescriptor iad; // Only needed on compound device
238
239 // Control
240 InterfaceDescriptor cif; //
241 CDCCSInterfaceDescriptor header;
242 CMFunctionalDescriptor callManagement; // Call Management
243 ACMFunctionalDescriptor controlManagement; // ACM
244 CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION
245 EndpointDescriptor cifin;
246
247 // Data
248 InterfaceDescriptor dif;
249 EndpointDescriptor in;
250 EndpointDescriptor out;
251 } CDCDescriptor;
252
253 typedef struct
254 {
255 InterfaceDescriptor msc;
256 EndpointDescriptor in;
257 EndpointDescriptor out;
258 } MSCDescriptor;
259
260 typedef struct
261 {
262 u8 len; // 9
263 u8 dtype; // 0x21
264 u8 addr;
265 u8 versionL; // 0x101
266 u8 versionH; // 0x101
267 u8 country;
268 u8 desctype; // 0x22 report
269 u8 descLenL;
270 u8 descLenH;
271 } HIDDescDescriptor;
272
273 typedef struct
274 {
275 InterfaceDescriptor hid;
276 HIDDescDescriptor desc;
277 EndpointDescriptor in;
278 } HIDDescriptor;
279
280
281 #define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
282 { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
283
284 #define D_CONFIG(_totalLength,_interfaces) \
285 { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) }
286
287 #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
288 { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
289
290 #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
291 { 7, 5, _addr,_attr,_packetSize, _interval }
292
293 #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
294 { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
295
296 #define D_HIDREPORT(_descriptorLength) \
297 { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 }
298
299 #define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
300 #define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
301
302
303 #endif No newline at end of file
@@ -0,0 +1,63
1
2
3 /* Copyright (c) 2011, Peter Barrett
4 **
5 ** Permission to use, copy, modify, and/or distribute this software for
6 ** any purpose with or without fee is hereby granted, provided that the
7 ** above copyright notice and this permission notice appear in all copies.
8 **
9 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
12 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
13 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
14 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 ** SOFTWARE.
17 */
18
19 #define CDC_ENABLED
20 #define HID_ENABLED
21
22
23 #ifdef CDC_ENABLED
24 #define CDC_INTERFACE_COUNT 2
25 #define CDC_ENPOINT_COUNT 3
26 #else
27 #define CDC_INTERFACE_COUNT 0
28 #define CDC_ENPOINT_COUNT 0
29 #endif
30
31 #ifdef HID_ENABLED
32 #define HID_INTERFACE_COUNT 1
33 #define HID_ENPOINT_COUNT 1
34 #else
35 #define HID_INTERFACE_COUNT 0
36 #define HID_ENPOINT_COUNT 0
37 #endif
38
39 #define CDC_ACM_INTERFACE 0 // CDC ACM
40 #define CDC_DATA_INTERFACE 1 // CDC Data
41 #define CDC_FIRST_ENDPOINT 1
42 #define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First
43 #define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1)
44 #define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2)
45
46 #define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface
47 #define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT)
48 #define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT)
49
50 #define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT)
51
52 #ifdef CDC_ENABLED
53 #define CDC_RX CDC_ENDPOINT_OUT
54 #define CDC_TX CDC_ENDPOINT_IN
55 #endif
56
57 #ifdef HID_ENABLED
58 #define HID_TX HID_ENDPOINT_INT
59 #endif
60
61 #define IMANUFACTURER 1
62 #define IPRODUCT 2
63
@@ -0,0 +1,88
1 /*
2 * Udp.cpp: Library to send/receive UDP packets.
3 *
4 * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
5 * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
6 * might not happen often in practice, but in larger network topologies, a UDP
7 * packet can be received out of sequence.
8 * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
9 * aware of it. Again, this may not be a concern in practice on small local networks.
10 * For more information, see http://www.cafeaulait.org/course/week12/35.html
11 *
12 * MIT License:
13 * Copyright (c) 2008 Bjoern Hartmann
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this software and associated documentation files (the "Software"), to deal
16 * in the Software without restriction, including without limitation the rights
17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 * copies of the Software, and to permit persons to whom the Software is
19 * furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 * THE SOFTWARE.
31 *
32 * bjoern@cs.stanford.edu 12/30/2008
33 */
34
35 #ifndef udp_h
36 #define udp_h
37
38 #include <Stream.h>
39 #include <IPAddress.h>
40
41 class UDP : public Stream {
42
43 public:
44 virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
45 virtual void stop() =0; // Finish with the UDP socket
46
47 // Sending UDP packets
48
49 // Start building up a packet to send to the remote host specific in ip and port
50 // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
51 virtual int beginPacket(IPAddress ip, uint16_t port) =0;
52 // Start building up a packet to send to the remote host specific in host and port
53 // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
54 virtual int beginPacket(const char *host, uint16_t port) =0;
55 // Finish off this packet and send it
56 // Returns 1 if the packet was sent successfully, 0 if there was an error
57 virtual int endPacket() =0;
58 // Write a single byte into the packet
59 virtual size_t write(uint8_t) =0;
60 // Write size bytes from buffer into the packet
61 virtual size_t write(const uint8_t *buffer, size_t size) =0;
62
63 // Start processing the next available incoming packet
64 // Returns the size of the packet in bytes, or 0 if no packets are available
65 virtual int parsePacket() =0;
66 // Number of bytes remaining in the current packet
67 virtual int available() =0;
68 // Read a single byte from the current packet
69 virtual int read() =0;
70 // Read up to len bytes from the current packet and place them into buffer
71 // Returns the number of bytes read, or 0 if none are available
72 virtual int read(unsigned char* buffer, size_t len) =0;
73 // Read up to len characters from the current packet and place them into buffer
74 // Returns the number of characters read, or 0 if none are available
75 virtual int read(char* buffer, size_t len) =0;
76 // Return the next byte from the current packet without moving on to the next byte
77 virtual int peek() =0;
78 virtual void flush() =0; // Finish reading the current packet
79
80 // Return the IP address of the host who sent the current incoming packet
81 virtual IPAddress remoteIP() =0;
82 // Return the port of the host who sent the current incoming packet
83 virtual uint16_t remotePort() =0;
84 protected:
85 uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
86 };
87
88 #endif
@@ -0,0 +1,168
1 /*
2 WCharacter.h - Character utility functions for Wiring & Arduino
3 Copyright (c) 2010 Hernando Barragan. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef Character_h
21 #define Character_h
22
23 #include <ctype.h>
24
25 // WCharacter.h prototypes
26 inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
27 inline boolean isAlpha(int c) __attribute__((always_inline));
28 inline boolean isAscii(int c) __attribute__((always_inline));
29 inline boolean isWhitespace(int c) __attribute__((always_inline));
30 inline boolean isControl(int c) __attribute__((always_inline));
31 inline boolean isDigit(int c) __attribute__((always_inline));
32 inline boolean isGraph(int c) __attribute__((always_inline));
33 inline boolean isLowerCase(int c) __attribute__((always_inline));
34 inline boolean isPrintable(int c) __attribute__((always_inline));
35 inline boolean isPunct(int c) __attribute__((always_inline));
36 inline boolean isSpace(int c) __attribute__((always_inline));
37 inline boolean isUpperCase(int c) __attribute__((always_inline));
38 inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
39 inline int toAscii(int c) __attribute__((always_inline));
40 inline int toLowerCase(int c) __attribute__((always_inline));
41 inline int toUpperCase(int c)__attribute__((always_inline));
42
43
44 // Checks for an alphanumeric character.
45 // It is equivalent to (isalpha(c) || isdigit(c)).
46 inline boolean isAlphaNumeric(int c)
47 {
48 return ( isalnum(c) == 0 ? false : true);
49 }
50
51
52 // Checks for an alphabetic character.
53 // It is equivalent to (isupper(c) || islower(c)).
54 inline boolean isAlpha(int c)
55 {
56 return ( isalpha(c) == 0 ? false : true);
57 }
58
59
60 // Checks whether c is a 7-bit unsigned char value
61 // that fits into the ASCII character set.
62 inline boolean isAscii(int c)
63 {
64 return ( isascii (c) == 0 ? false : true);
65 }
66
67
68 // Checks for a blank character, that is, a space or a tab.
69 inline boolean isWhitespace(int c)
70 {
71 return ( isblank (c) == 0 ? false : true);
72 }
73
74
75 // Checks for a control character.
76 inline boolean isControl(int c)
77 {
78 return ( iscntrl (c) == 0 ? false : true);
79 }
80
81
82 // Checks for a digit (0 through 9).
83 inline boolean isDigit(int c)
84 {
85 return ( isdigit (c) == 0 ? false : true);
86 }
87
88
89 // Checks for any printable character except space.
90 inline boolean isGraph(int c)
91 {
92 return ( isgraph (c) == 0 ? false : true);
93 }
94
95
96 // Checks for a lower-case character.
97 inline boolean isLowerCase(int c)
98 {
99 return (islower (c) == 0 ? false : true);
100 }
101
102
103 // Checks for any printable character including space.
104 inline boolean isPrintable(int c)
105 {
106 return ( isprint (c) == 0 ? false : true);
107 }
108
109
110 // Checks for any printable character which is not a space
111 // or an alphanumeric character.
112 inline boolean isPunct(int c)
113 {
114 return ( ispunct (c) == 0 ? false : true);
115 }
116
117
118 // Checks for white-space characters. For the avr-libc library,
119 // these are: space, formfeed ('\f'), newline ('\n'), carriage
120 // return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
121 inline boolean isSpace(int c)
122 {
123 return ( isspace (c) == 0 ? false : true);
124 }
125
126
127 // Checks for an uppercase letter.
128 inline boolean isUpperCase(int c)
129 {
130 return ( isupper (c) == 0 ? false : true);
131 }
132
133
134 // Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
135 // 8 9 a b c d e f A B C D E F.
136 inline boolean isHexadecimalDigit(int c)
137 {
138 return ( isxdigit (c) == 0 ? false : true);
139 }
140
141
142 // Converts c to a 7-bit unsigned char value that fits into the
143 // ASCII character set, by clearing the high-order bits.
144 inline int toAscii(int c)
145 {
146 return toascii (c);
147 }
148
149
150 // Warning:
151 // Many people will be unhappy if you use this function.
152 // This function will convert accented letters into random
153 // characters.
154
155 // Converts the letter c to lower case, if possible.
156 inline int toLowerCase(int c)
157 {
158 return tolower (c);
159 }
160
161
162 // Converts the letter c to upper case, if possible.
163 inline int toUpperCase(int c)
164 {
165 return toupper (c);
166 }
167
168 #endif No newline at end of file
@@ -0,0 +1,334
1 /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3 /*
4 Part of the Wiring project - http://wiring.uniandes.edu.co
5
6 Copyright (c) 2004-05 Hernando Barragan
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General
19 Public License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 Boston, MA 02111-1307 USA
22
23 Modified 24 November 2006 by David A. Mellis
24 Modified 1 August 2010 by Mark Sproul
25 */
26
27 #include <inttypes.h>
28 #include <avr/io.h>
29 #include <avr/interrupt.h>
30 #include <avr/pgmspace.h>
31 #include <stdio.h>
32
33 #include "wiring_private.h"
34
35 static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
36 // volatile static voidFuncPtr twiIntFunc;
37
38 void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
39 if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
40 intFunc[interruptNum] = userFunc;
41
42 // Configure the interrupt mode (trigger on low input, any change, rising
43 // edge, or falling edge). The mode constants were chosen to correspond
44 // to the configuration bits in the hardware register, so we simply shift
45 // the mode into place.
46
47 // Enable the interrupt.
48
49 switch (interruptNum) {
50 #if defined(__AVR_ATmega32U4__)
51 // I hate doing this, but the register assignment differs between the 1280/2560
52 // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
53 // even present on the 32U4 this is the only way to distinguish between them.
54 case 0:
55 EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
56 EIMSK |= (1<<INT0);
57 break;
58 case 1:
59 EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
60 EIMSK |= (1<<INT1);
61 break;
62 case 2:
63 EICRA = (EICRA & ~((1<<ISC20) | (1<<ISC21))) | (mode << ISC20);
64 EIMSK |= (1<<INT2);
65 break;
66 case 3:
67 EICRA = (EICRA & ~((1<<ISC30) | (1<<ISC31))) | (mode << ISC30);
68 EIMSK |= (1<<INT3);
69 break;
70 case 4:
71 EICRB = (EICRB & ~((1<<ISC60) | (1<<ISC61))) | (mode << ISC60);
72 EIMSK |= (1<<INT6);
73 break;
74 #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
75 case 2:
76 EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
77 EIMSK |= (1 << INT0);
78 break;
79 case 3:
80 EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
81 EIMSK |= (1 << INT1);
82 break;
83 case 4:
84 EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
85 EIMSK |= (1 << INT2);
86 break;
87 case 5:
88 EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
89 EIMSK |= (1 << INT3);
90 break;
91 case 0:
92 EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
93 EIMSK |= (1 << INT4);
94 break;
95 case 1:
96 EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
97 EIMSK |= (1 << INT5);
98 break;
99 case 6:
100 EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
101 EIMSK |= (1 << INT6);
102 break;
103 case 7:
104 EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
105 EIMSK |= (1 << INT7);
106 break;
107 #else
108 case 0:
109 #if defined(EICRA) && defined(ISC00) && defined(EIMSK)
110 EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
111 EIMSK |= (1 << INT0);
112 #elif defined(MCUCR) && defined(ISC00) && defined(GICR)
113 MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
114 GICR |= (1 << INT0);
115 #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK)
116 MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
117 GIMSK |= (1 << INT0);
118 #else
119 #error attachInterrupt not finished for this CPU (case 0)
120 #endif
121 break;
122
123 case 1:
124 #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK)
125 EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
126 EIMSK |= (1 << INT1);
127 #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR)
128 MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
129 GICR |= (1 << INT1);
130 #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK)
131 MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
132 GIMSK |= (1 << INT1);
133 #else
134 #warning attachInterrupt may need some more work for this cpu (case 1)
135 #endif
136 break;
137
138 case 2:
139 #if defined(EICRA) && defined(ISC20) && defined(ISC21) && defined(EIMSK)
140 EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
141 EIMSK |= (1 << INT2);
142 #elif defined(MCUCR) && defined(ISC20) && defined(ISC21) && defined(GICR)
143 MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
144 GICR |= (1 << INT2);
145 #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK)
146 MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
147 GIMSK |= (1 << INT2);
148 #endif
149 break;
150 #endif
151 }
152 }
153 }
154
155 void detachInterrupt(uint8_t interruptNum) {
156 if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
157 // Disable the interrupt. (We can't assume that interruptNum is equal
158 // to the number of the EIMSK bit to clear, as this isn't true on the
159 // ATmega8. There, INT0 is 6 and INT1 is 7.)
160 switch (interruptNum) {
161 #if defined(__AVR_ATmega32U4__)
162 case 0:
163 EIMSK &= ~(1<<INT0);
164 break;
165 case 1:
166 EIMSK &= ~(1<<INT1);
167 break;
168 case 2:
169 EIMSK &= ~(1<<INT2);
170 break;
171 case 3:
172 EIMSK &= ~(1<<INT3);
173 break;
174 case 4:
175 EIMSK &= ~(1<<INT6);
176 break;
177 #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
178 case 2:
179 EIMSK &= ~(1 << INT0);
180 break;
181 case 3:
182 EIMSK &= ~(1 << INT1);
183 break;
184 case 4:
185 EIMSK &= ~(1 << INT2);
186 break;
187 case 5:
188 EIMSK &= ~(1 << INT3);
189 break;
190 case 0:
191 EIMSK &= ~(1 << INT4);
192 break;
193 case 1:
194 EIMSK &= ~(1 << INT5);
195 break;
196 case 6:
197 EIMSK &= ~(1 << INT6);
198 break;
199 case 7:
200 EIMSK &= ~(1 << INT7);
201 break;
202 #else
203 case 0:
204 #if defined(EIMSK) && defined(INT0)
205 EIMSK &= ~(1 << INT0);
206 #elif defined(GICR) && defined(ISC00)
207 GICR &= ~(1 << INT0); // atmega32
208 #elif defined(GIMSK) && defined(INT0)
209 GIMSK &= ~(1 << INT0);
210 #else
211 #error detachInterrupt not finished for this cpu
212 #endif
213 break;
214
215 case 1:
216 #if defined(EIMSK) && defined(INT1)
217 EIMSK &= ~(1 << INT1);
218 #elif defined(GICR) && defined(INT1)
219 GICR &= ~(1 << INT1); // atmega32
220 #elif defined(GIMSK) && defined(INT1)
221 GIMSK &= ~(1 << INT1);
222 #else
223 #warning detachInterrupt may need some more work for this cpu (case 1)
224 #endif
225 break;
226 #endif
227 }
228
229 intFunc[interruptNum] = 0;
230 }
231 }
232
233 /*
234 void attachInterruptTwi(void (*userFunc)(void) ) {
235 twiIntFunc = userFunc;
236 }
237 */
238
239 #if defined(__AVR_ATmega32U4__)
240 ISR(INT0_vect) {
241 if(intFunc[EXTERNAL_INT_0])
242 intFunc[EXTERNAL_INT_0]();
243 }
244
245 ISR(INT1_vect) {
246 if(intFunc[EXTERNAL_INT_1])
247 intFunc[EXTERNAL_INT_1]();
248 }
249
250 ISR(INT2_vect) {
251 if(intFunc[EXTERNAL_INT_2])
252 intFunc[EXTERNAL_INT_2]();
253 }
254
255 ISR(INT3_vect) {
256 if(intFunc[EXTERNAL_INT_3])
257 intFunc[EXTERNAL_INT_3]();
258 }
259
260 ISR(INT6_vect) {
261 if(intFunc[EXTERNAL_INT_4])
262 intFunc[EXTERNAL_INT_4]();
263 }
264
265 #elif defined(EICRA) && defined(EICRB)
266
267 ISR(INT0_vect) {
268 if(intFunc[EXTERNAL_INT_2])
269 intFunc[EXTERNAL_INT_2]();
270 }
271
272 ISR(INT1_vect) {
273 if(intFunc[EXTERNAL_INT_3])
274 intFunc[EXTERNAL_INT_3]();
275 }
276
277 ISR(INT2_vect) {
278 if(intFunc[EXTERNAL_INT_4])
279 intFunc[EXTERNAL_INT_4]();
280 }
281
282 ISR(INT3_vect) {
283 if(intFunc[EXTERNAL_INT_5])
284 intFunc[EXTERNAL_INT_5]();
285 }
286
287 ISR(INT4_vect) {
288 if(intFunc[EXTERNAL_INT_0])
289 intFunc[EXTERNAL_INT_0]();
290 }
291
292 ISR(INT5_vect) {
293 if(intFunc[EXTERNAL_INT_1])
294 intFunc[EXTERNAL_INT_1]();
295 }
296
297 ISR(INT6_vect) {
298 if(intFunc[EXTERNAL_INT_6])
299 intFunc[EXTERNAL_INT_6]();
300 }
301
302 ISR(INT7_vect) {
303 if(intFunc[EXTERNAL_INT_7])
304 intFunc[EXTERNAL_INT_7]();
305 }
306
307 #else
308
309 ISR(INT0_vect) {
310 if(intFunc[EXTERNAL_INT_0])
311 intFunc[EXTERNAL_INT_0]();
312 }
313
314 ISR(INT1_vect) {
315 if(intFunc[EXTERNAL_INT_1])
316 intFunc[EXTERNAL_INT_1]();
317 }
318
319 #if defined(EICRA) && defined(ISC20)
320 ISR(INT2_vect) {
321 if(intFunc[EXTERNAL_INT_2])
322 intFunc[EXTERNAL_INT_2]();
323 }
324 #endif
325
326 #endif
327
328 /*
329 ISR(TWI_vect) {
330 if(twiIntFunc)
331 twiIntFunc();
332 }
333 */
334
@@ -0,0 +1,60
1 /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3 /*
4 Part of the Wiring project - http://wiring.org.co
5 Copyright (c) 2004-06 Hernando Barragan
6 Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General
19 Public License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 Boston, MA 02111-1307 USA
22
23 $Id$
24 */
25
26 extern "C" {
27 #include "stdlib.h"
28 }
29
30 void randomSeed(unsigned int seed)
31 {
32 if (seed != 0) {
33 srandom(seed);
34 }
35 }
36
37 long random(long howbig)
38 {
39 if (howbig == 0) {
40 return 0;
41 }
42 return random() % howbig;
43 }
44
45 long random(long howsmall, long howbig)
46 {
47 if (howsmall >= howbig) {
48 return howsmall;
49 }
50 long diff = howbig - howsmall;
51 return random(diff) + howsmall;
52 }
53
54 long map(long x, long in_min, long in_max, long out_min, long out_max)
55 {
56 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
57 }
58
59 unsigned int makeWord(unsigned int w) { return w; }
60 unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } No newline at end of file
This diff has been collapsed as it changes many lines, (744 lines changed) Show them Hide them
@@ -0,0 +1,744
1 /*
2 WString.cpp - String library for Wiring & Arduino
3 ...mostly rewritten by Paul Stoffregen...
4 Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
5 Copyright 2011, Paul Stoffregen, paul@pjrc.com
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "WString.h"
23
24 /*********************************************/
25 /* Constructors */
26 /*********************************************/
27
28 String::String(const char *cstr)
29 {
30 init();
31 if (cstr) copy(cstr, strlen(cstr));
32 }
33
34 String::String(const String &value)
35 {
36 init();
37 *this = value;
38 }
39
40 String::String(const __FlashStringHelper *pstr)
41 {
42 init();
43 *this = pstr;
44 }
45
46 #ifdef __GXX_EXPERIMENTAL_CXX0X__
47 String::String(String &&rval)
48 {
49 init();
50 move(rval);
51 }
52 String::String(StringSumHelper &&rval)
53 {
54 init();
55 move(rval);
56 }
57 #endif
58
59 String::String(char c)
60 {
61 init();
62 char buf[2];
63 buf[0] = c;
64 buf[1] = 0;
65 *this = buf;
66 }
67
68 String::String(unsigned char value, unsigned char base)
69 {
70 init();
71 char buf[1 + 8 * sizeof(unsigned char)];
72 utoa(value, buf, base);
73 *this = buf;
74 }
75
76 String::String(int value, unsigned char base)
77 {
78 init();
79 char buf[2 + 8 * sizeof(int)];
80 itoa(value, buf, base);
81 *this = buf;
82 }
83
84 String::String(unsigned int value, unsigned char base)
85 {
86 init();
87 char buf[1 + 8 * sizeof(unsigned int)];
88 utoa(value, buf, base);
89 *this = buf;
90 }
91
92 String::String(long value, unsigned char base)
93 {
94 init();
95 char buf[2 + 8 * sizeof(long)];
96 ltoa(value, buf, base);
97 *this = buf;
98 }
99
100 String::String(unsigned long value, unsigned char base)
101 {
102 init();
103 char buf[1 + 8 * sizeof(unsigned long)];
104 ultoa(value, buf, base);
105 *this = buf;
106 }
107
108 String::String(float value, unsigned char decimalPlaces)
109 {
110 init();
111 char buf[33];
112 *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
113 }
114
115 String::String(double value, unsigned char decimalPlaces)
116 {
117 init();
118 char buf[33];
119 *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
120 }
121
122 String::~String()
123 {
124 free(buffer);
125 }
126
127 /*********************************************/
128 /* Memory Management */
129 /*********************************************/
130
131 inline void String::init(void)
132 {
133 buffer = NULL;
134 capacity = 0;
135 len = 0;
136 }
137
138 void String::invalidate(void)
139 {
140 if (buffer) free(buffer);
141 buffer = NULL;
142 capacity = len = 0;
143 }
144
145 unsigned char String::reserve(unsigned int size)
146 {
147 if (buffer && capacity >= size) return 1;
148 if (changeBuffer(size)) {
149 if (len == 0) buffer[0] = 0;
150 return 1;
151 }
152 return 0;
153 }
154
155 unsigned char String::changeBuffer(unsigned int maxStrLen)
156 {
157 char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
158 if (newbuffer) {
159 buffer = newbuffer;
160 capacity = maxStrLen;
161 return 1;
162 }
163 return 0;
164 }
165
166 /*********************************************/
167 /* Copy and Move */
168 /*********************************************/
169
170 String & String::copy(const char *cstr, unsigned int length)
171 {
172 if (!reserve(length)) {
173 invalidate();
174 return *this;
175 }
176 len = length;
177 strcpy(buffer, cstr);
178 return *this;
179 }
180
181 String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
182 {
183 if (!reserve(length)) {
184 invalidate();
185 return *this;
186 }
187 len = length;
188 strcpy_P(buffer, (PGM_P)pstr);
189 return *this;
190 }
191
192 #ifdef __GXX_EXPERIMENTAL_CXX0X__
193 void String::move(String &rhs)
194 {
195 if (buffer) {
196 if (capacity >= rhs.len) {
197 strcpy(buffer, rhs.buffer);
198 len = rhs.len;
199 rhs.len = 0;
200 return;
201 } else {
202 free(buffer);
203 }
204 }
205 buffer = rhs.buffer;
206 capacity = rhs.capacity;
207 len = rhs.len;
208 rhs.buffer = NULL;
209 rhs.capacity = 0;
210 rhs.len = 0;
211 }
212 #endif
213
214 String & String::operator = (const String &rhs)
215 {
216 if (this == &rhs) return *this;
217
218 if (rhs.buffer) copy(rhs.buffer, rhs.len);
219 else invalidate();
220
221 return *this;
222 }
223
224 #ifdef __GXX_EXPERIMENTAL_CXX0X__
225 String & String::operator = (String &&rval)
226 {
227 if (this != &rval) move(rval);
228 return *this;
229 }
230
231 String & String::operator = (StringSumHelper &&rval)
232 {
233 if (this != &rval) move(rval);
234 return *this;
235 }
236 #endif
237
238 String & String::operator = (const char *cstr)
239 {
240 if (cstr) copy(cstr, strlen(cstr));
241 else invalidate();
242
243 return *this;
244 }
245
246 String & String::operator = (const __FlashStringHelper *pstr)
247 {
248 if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
249 else invalidate();
250
251 return *this;
252 }
253
254 /*********************************************/
255 /* concat */
256 /*********************************************/
257
258 unsigned char String::concat(const String &s)
259 {
260 return concat(s.buffer, s.len);
261 }
262
263 unsigned char String::concat(const char *cstr, unsigned int length)
264 {
265 unsigned int newlen = len + length;
266 if (!cstr) return 0;
267 if (length == 0) return 1;
268 if (!reserve(newlen)) return 0;
269 strcpy(buffer + len, cstr);
270 len = newlen;
271 return 1;
272 }
273
274 unsigned char String::concat(const char *cstr)
275 {
276 if (!cstr) return 0;
277 return concat(cstr, strlen(cstr));
278 }
279
280 unsigned char String::concat(char c)
281 {
282 char buf[2];
283 buf[0] = c;
284 buf[1] = 0;
285 return concat(buf, 1);
286 }
287
288 unsigned char String::concat(unsigned char num)
289 {
290 char buf[1 + 3 * sizeof(unsigned char)];
291 itoa(num, buf, 10);
292 return concat(buf, strlen(buf));
293 }
294
295 unsigned char String::concat(int num)
296 {
297 char buf[2 + 3 * sizeof(int)];
298 itoa(num, buf, 10);
299 return concat(buf, strlen(buf));
300 }
301
302 unsigned char String::concat(unsigned int num)
303 {
304 char buf[1 + 3 * sizeof(unsigned int)];
305 utoa(num, buf, 10);
306 return concat(buf, strlen(buf));
307 }
308
309 unsigned char String::concat(long num)
310 {
311 char buf[2 + 3 * sizeof(long)];
312 ltoa(num, buf, 10);
313 return concat(buf, strlen(buf));
314 }
315
316 unsigned char String::concat(unsigned long num)
317 {
318 char buf[1 + 3 * sizeof(unsigned long)];
319 ultoa(num, buf, 10);
320 return concat(buf, strlen(buf));
321 }
322
323 unsigned char String::concat(float num)
324 {
325 char buf[20];
326 char* string = dtostrf(num, 4, 2, buf);
327 return concat(string, strlen(string));
328 }
329
330 unsigned char String::concat(double num)
331 {
332 char buf[20];
333 char* string = dtostrf(num, 4, 2, buf);
334 return concat(string, strlen(string));
335 }
336
337 unsigned char String::concat(const __FlashStringHelper * str)
338 {
339 if (!str) return 0;
340 int length = strlen_P((const char *) str);
341 if (length == 0) return 1;
342 unsigned int newlen = len + length;
343 if (!reserve(newlen)) return 0;
344 strcpy_P(buffer + len, (const char *) str);
345 len = newlen;
346 return 1;
347 }
348
349 /*********************************************/
350 /* Concatenate */
351 /*********************************************/
352
353 StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
354 {
355 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
356 if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
357 return a;
358 }
359
360 StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
361 {
362 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
363 if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
364 return a;
365 }
366
367 StringSumHelper & operator + (const StringSumHelper &lhs, char c)
368 {
369 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
370 if (!a.concat(c)) a.invalidate();
371 return a;
372 }
373
374 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
375 {
376 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
377 if (!a.concat(num)) a.invalidate();
378 return a;
379 }
380
381 StringSumHelper & operator + (const StringSumHelper &lhs, int num)
382 {
383 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
384 if (!a.concat(num)) a.invalidate();
385 return a;
386 }
387
388 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
389 {
390 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
391 if (!a.concat(num)) a.invalidate();
392 return a;
393 }
394
395 StringSumHelper & operator + (const StringSumHelper &lhs, long num)
396 {
397 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
398 if (!a.concat(num)) a.invalidate();
399 return a;
400 }
401
402 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
403 {
404 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
405 if (!a.concat(num)) a.invalidate();
406 return a;
407 }
408
409 StringSumHelper & operator + (const StringSumHelper &lhs, float num)
410 {
411 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
412 if (!a.concat(num)) a.invalidate();
413 return a;
414 }
415
416 StringSumHelper & operator + (const StringSumHelper &lhs, double num)
417 {
418 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
419 if (!a.concat(num)) a.invalidate();
420 return a;
421 }
422
423 StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
424 {
425 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
426 if (!a.concat(rhs)) a.invalidate();
427 return a;
428 }
429
430 /*********************************************/
431 /* Comparison */
432 /*********************************************/
433
434 int String::compareTo(const String &s) const
435 {
436 if (!buffer || !s.buffer) {
437 if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
438 if (buffer && len > 0) return *(unsigned char *)buffer;
439 return 0;
440 }
441 return strcmp(buffer, s.buffer);
442 }
443
444 unsigned char String::equals(const String &s2) const
445 {
446 return (len == s2.len && compareTo(s2) == 0);
447 }
448
449 unsigned char String::equals(const char *cstr) const
450 {
451 if (len == 0) return (cstr == NULL || *cstr == 0);
452 if (cstr == NULL) return buffer[0] == 0;
453 return strcmp(buffer, cstr) == 0;
454 }
455
456 unsigned char String::operator<(const String &rhs) const
457 {
458 return compareTo(rhs) < 0;
459 }
460
461 unsigned char String::operator>(const String &rhs) const
462 {
463 return compareTo(rhs) > 0;
464 }
465
466 unsigned char String::operator<=(const String &rhs) const
467 {
468 return compareTo(rhs) <= 0;
469 }
470
471 unsigned char String::operator>=(const String &rhs) const
472 {
473 return compareTo(rhs) >= 0;
474 }
475
476 unsigned char String::equalsIgnoreCase( const String &s2 ) const
477 {
478 if (this == &s2) return 1;
479 if (len != s2.len) return 0;
480 if (len == 0) return 1;
481 const char *p1 = buffer;
482 const char *p2 = s2.buffer;
483 while (*p1) {
484 if (tolower(*p1++) != tolower(*p2++)) return 0;
485 }
486 return 1;
487 }
488
489 unsigned char String::startsWith( const String &s2 ) const
490 {
491 if (len < s2.len) return 0;
492 return startsWith(s2, 0);
493 }
494
495 unsigned char String::startsWith( const String &s2, unsigned int offset ) const
496 {
497 if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
498 return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
499 }
500
501 unsigned char String::endsWith( const String &s2 ) const
502 {
503 if ( len < s2.len || !buffer || !s2.buffer) return 0;
504 return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
505 }
506
507 /*********************************************/
508 /* Character Access */
509 /*********************************************/
510
511 char String::charAt(unsigned int loc) const
512 {
513 return operator[](loc);
514 }
515
516 void String::setCharAt(unsigned int loc, char c)
517 {
518 if (loc < len) buffer[loc] = c;
519 }
520
521 char & String::operator[](unsigned int index)
522 {
523 static char dummy_writable_char;
524 if (index >= len || !buffer) {
525 dummy_writable_char = 0;
526 return dummy_writable_char;
527 }
528 return buffer[index];
529 }
530
531 char String::operator[]( unsigned int index ) const
532 {
533 if (index >= len || !buffer) return 0;
534 return buffer[index];
535 }
536
537 void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
538 {
539 if (!bufsize || !buf) return;
540 if (index >= len) {
541 buf[0] = 0;
542 return;
543 }
544 unsigned int n = bufsize - 1;
545 if (n > len - index) n = len - index;
546 strncpy((char *)buf, buffer + index, n);
547 buf[n] = 0;
548 }
549
550 /*********************************************/
551 /* Search */
552 /*********************************************/
553
554 int String::indexOf(char c) const
555 {
556 return indexOf(c, 0);
557 }
558
559 int String::indexOf( char ch, unsigned int fromIndex ) const
560 {
561 if (fromIndex >= len) return -1;
562 const char* temp = strchr(buffer + fromIndex, ch);
563 if (temp == NULL) return -1;
564 return temp - buffer;
565 }
566
567 int String::indexOf(const String &s2) const
568 {
569 return indexOf(s2, 0);
570 }
571
572 int String::indexOf(const String &s2, unsigned int fromIndex) const
573 {
574 if (fromIndex >= len) return -1;
575 const char *found = strstr(buffer + fromIndex, s2.buffer);
576 if (found == NULL) return -1;
577 return found - buffer;
578 }
579
580 int String::lastIndexOf( char theChar ) const
581 {
582 return lastIndexOf(theChar, len - 1);
583 }
584
585 int String::lastIndexOf(char ch, unsigned int fromIndex) const
586 {
587 if (fromIndex >= len) return -1;
588 char tempchar = buffer[fromIndex + 1];
589 buffer[fromIndex + 1] = '\0';
590 char* temp = strrchr( buffer, ch );
591 buffer[fromIndex + 1] = tempchar;
592 if (temp == NULL) return -1;
593 return temp - buffer;
594 }
595
596 int String::lastIndexOf(const String &s2) const
597 {
598 return lastIndexOf(s2, len - s2.len);
599 }
600
601 int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
602 {
603 if (s2.len == 0 || len == 0 || s2.len > len) return -1;
604 if (fromIndex >= len) fromIndex = len - 1;
605 int found = -1;
606 for (char *p = buffer; p <= buffer + fromIndex; p++) {
607 p = strstr(p, s2.buffer);
608 if (!p) break;
609 if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
610 }
611 return found;
612 }
613
614 String String::substring(unsigned int left, unsigned int right) const
615 {
616 if (left > right) {
617 unsigned int temp = right;
618 right = left;
619 left = temp;
620 }
621 String out;
622 if (left > len) return out;
623 if (right > len) right = len;
624 char temp = buffer[right]; // save the replaced character
625 buffer[right] = '\0';
626 out = buffer + left; // pointer arithmetic
627 buffer[right] = temp; //restore character
628 return out;
629 }
630
631 /*********************************************/
632 /* Modification */
633 /*********************************************/
634
635 void String::replace(char find, char replace)
636 {
637 if (!buffer) return;
638 for (char *p = buffer; *p; p++) {
639 if (*p == find) *p = replace;
640 }
641 }
642
643 void String::replace(const String& find, const String& replace)
644 {
645 if (len == 0 || find.len == 0) return;
646 int diff = replace.len - find.len;
647 char *readFrom = buffer;
648 char *foundAt;
649 if (diff == 0) {
650 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
651 memcpy(foundAt, replace.buffer, replace.len);
652 readFrom = foundAt + replace.len;
653 }
654 } else if (diff < 0) {
655 char *writeTo = buffer;
656 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
657 unsigned int n = foundAt - readFrom;
658 memcpy(writeTo, readFrom, n);
659 writeTo += n;
660 memcpy(writeTo, replace.buffer, replace.len);
661 writeTo += replace.len;
662 readFrom = foundAt + find.len;
663 len += diff;
664 }
665 strcpy(writeTo, readFrom);
666 } else {
667 unsigned int size = len; // compute size needed for result
668 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
669 readFrom = foundAt + find.len;
670 size += diff;
671 }
672 if (size == len) return;
673 if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
674 int index = len - 1;
675 while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
676 readFrom = buffer + index + find.len;
677 memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
678 len += diff;
679 buffer[len] = 0;
680 memcpy(buffer + index, replace.buffer, replace.len);
681 index--;
682 }
683 }
684 }
685
686 void String::remove(unsigned int index){
687 if (index >= len) { return; }
688 int count = len - index;
689 remove(index, count);
690 }
691
692 void String::remove(unsigned int index, unsigned int count){
693 if (index >= len) { return; }
694 if (count <= 0) { return; }
695 if (index + count > len) { count = len - index; }
696 char *writeTo = buffer + index;
697 len = len - count;
698 strncpy(writeTo, buffer + index + count,len - index);
699 buffer[len] = 0;
700 }
701
702 void String::toLowerCase(void)
703 {
704 if (!buffer) return;
705 for (char *p = buffer; *p; p++) {
706 *p = tolower(*p);
707 }
708 }
709
710 void String::toUpperCase(void)
711 {
712 if (!buffer) return;
713 for (char *p = buffer; *p; p++) {
714 *p = toupper(*p);
715 }
716 }
717
718 void String::trim(void)
719 {
720 if (!buffer || len == 0) return;
721 char *begin = buffer;
722 while (isspace(*begin)) begin++;
723 char *end = buffer + len - 1;
724 while (isspace(*end) && end >= begin) end--;
725 len = end + 1 - begin;
726 if (begin > buffer) memcpy(buffer, begin, len);
727 buffer[len] = 0;
728 }
729
730 /*********************************************/
731 /* Parsing / Conversion */
732 /*********************************************/
733
734 long String::toInt(void) const
735 {
736 if (buffer) return atol(buffer);
737 return 0;
738 }
739
740 float String::toFloat(void) const
741 {
742 if (buffer) return float(atof(buffer));
743 return 0;
744 }
@@ -0,0 +1,224
1 /*
2 WString.h - String library for Wiring & Arduino
3 ...mostly rewritten by Paul Stoffregen...
4 Copyright (c) 2009-10 Hernando Barragan. All right reserved.
5 Copyright 2011, Paul Stoffregen, paul@pjrc.com
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifndef String_class_h
23 #define String_class_h
24 #ifdef __cplusplus
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <avr/pgmspace.h>
30
31 // When compiling programs with this class, the following gcc parameters
32 // dramatically increase performance and memory (RAM) efficiency, typically
33 // with little or no increase in code size.
34 // -felide-constructors
35 // -std=c++0x
36
37 class __FlashStringHelper;
38 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
39
40 // An inherited class for holding the result of a concatenation. These
41 // result objects are assumed to be writable by subsequent concatenations.
42 class StringSumHelper;
43
44 // The string class
45 class String
46 {
47 // use a function pointer to allow for "if (s)" without the
48 // complications of an operator bool(). for more information, see:
49 // http://www.artima.com/cppsource/safebool.html
50 typedef void (String::*StringIfHelperType)() const;
51 void StringIfHelper() const {}
52
53 public:
54 // constructors
55 // creates a copy of the initial value.
56 // if the initial value is null or invalid, or if memory allocation
57 // fails, the string will be marked as invalid (i.e. "if (s)" will
58 // be false).
59 String(const char *cstr = "");
60 String(const String &str);
61 String(const __FlashStringHelper *str);
62 #ifdef __GXX_EXPERIMENTAL_CXX0X__
63 String(String &&rval);
64 String(StringSumHelper &&rval);
65 #endif
66 explicit String(char c);
67 explicit String(unsigned char, unsigned char base=10);
68 explicit String(int, unsigned char base=10);
69 explicit String(unsigned int, unsigned char base=10);
70 explicit String(long, unsigned char base=10);
71 explicit String(unsigned long, unsigned char base=10);
72 explicit String(float, unsigned char decimalPlaces=2);
73 explicit String(double, unsigned char decimalPlaces=2);
74 ~String(void);
75
76 // memory management
77 // return true on success, false on failure (in which case, the string
78 // is left unchanged). reserve(0), if successful, will validate an
79 // invalid string (i.e., "if (s)" will be true afterwards)
80 unsigned char reserve(unsigned int size);
81 inline unsigned int length(void) const {return len;}
82
83 // creates a copy of the assigned value. if the value is null or
84 // invalid, or if the memory allocation fails, the string will be
85 // marked as invalid ("if (s)" will be false).
86 String & operator = (const String &rhs);
87 String & operator = (const char *cstr);
88 String & operator = (const __FlashStringHelper *str);
89 #ifdef __GXX_EXPERIMENTAL_CXX0X__
90 String & operator = (String &&rval);
91 String & operator = (StringSumHelper &&rval);
92 #endif
93
94 // concatenate (works w/ built-in types)
95
96 // returns true on success, false on failure (in which case, the string
97 // is left unchanged). if the argument is null or invalid, the
98 // concatenation is considered unsucessful.
99 unsigned char concat(const String &str);
100 unsigned char concat(const char *cstr);
101 unsigned char concat(char c);
102 unsigned char concat(unsigned char c);
103 unsigned char concat(int num);
104 unsigned char concat(unsigned int num);
105 unsigned char concat(long num);
106 unsigned char concat(unsigned long num);
107 unsigned char concat(float num);
108 unsigned char concat(double num);
109 unsigned char concat(const __FlashStringHelper * str);
110
111 // if there's not enough memory for the concatenated value, the string
112 // will be left unchanged (but this isn't signalled in any way)
113 String & operator += (const String &rhs) {concat(rhs); return (*this);}
114 String & operator += (const char *cstr) {concat(cstr); return (*this);}
115 String & operator += (char c) {concat(c); return (*this);}
116 String & operator += (unsigned char num) {concat(num); return (*this);}
117 String & operator += (int num) {concat(num); return (*this);}
118 String & operator += (unsigned int num) {concat(num); return (*this);}
119 String & operator += (long num) {concat(num); return (*this);}
120 String & operator += (unsigned long num) {concat(num); return (*this);}
121 String & operator += (float num) {concat(num); return (*this);}
122 String & operator += (double num) {concat(num); return (*this);}
123 String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
124
125 friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
126 friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
127 friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
128 friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
129 friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
130 friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
131 friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
132 friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
133 friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
134 friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
135 friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
136
137 // comparison (only works w/ Strings and "strings")
138 operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
139 int compareTo(const String &s) const;
140 unsigned char equals(const String &s) const;
141 unsigned char equals(const char *cstr) const;
142 unsigned char operator == (const String &rhs) const {return equals(rhs);}
143 unsigned char operator == (const char *cstr) const {return equals(cstr);}
144 unsigned char operator != (const String &rhs) const {return !equals(rhs);}
145 unsigned char operator != (const char *cstr) const {return !equals(cstr);}
146 unsigned char operator < (const String &rhs) const;
147 unsigned char operator > (const String &rhs) const;
148 unsigned char operator <= (const String &rhs) const;
149 unsigned char operator >= (const String &rhs) const;
150 unsigned char equalsIgnoreCase(const String &s) const;
151 unsigned char startsWith( const String &prefix) const;
152 unsigned char startsWith(const String &prefix, unsigned int offset) const;
153 unsigned char endsWith(const String &suffix) const;
154
155 // character acccess
156 char charAt(unsigned int index) const;
157 void setCharAt(unsigned int index, char c);
158 char operator [] (unsigned int index) const;
159 char& operator [] (unsigned int index);
160 void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
161 void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
162 {getBytes((unsigned char *)buf, bufsize, index);}
163 const char * c_str() const { return buffer; }
164
165 // search
166 int indexOf( char ch ) const;
167 int indexOf( char ch, unsigned int fromIndex ) const;
168 int indexOf( const String &str ) const;
169 int indexOf( const String &str, unsigned int fromIndex ) const;
170 int lastIndexOf( char ch ) const;
171 int lastIndexOf( char ch, unsigned int fromIndex ) const;
172 int lastIndexOf( const String &str ) const;
173 int lastIndexOf( const String &str, unsigned int fromIndex ) const;
174 String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
175 String substring( unsigned int beginIndex, unsigned int endIndex ) const;
176
177 // modification
178 void replace(char find, char replace);
179 void replace(const String& find, const String& replace);
180 void remove(unsigned int index);
181 void remove(unsigned int index, unsigned int count);
182 void toLowerCase(void);
183 void toUpperCase(void);
184 void trim(void);
185
186 // parsing/conversion
187 long toInt(void) const;
188 float toFloat(void) const;
189
190 protected:
191 char *buffer; // the actual char array
192 unsigned int capacity; // the array length minus one (for the '\0')
193 unsigned int len; // the String length (not counting the '\0')
194 protected:
195 void init(void);
196 void invalidate(void);
197 unsigned char changeBuffer(unsigned int maxStrLen);
198 unsigned char concat(const char *cstr, unsigned int length);
199
200 // copy and move
201 String & copy(const char *cstr, unsigned int length);
202 String & copy(const __FlashStringHelper *pstr, unsigned int length);
203 #ifdef __GXX_EXPERIMENTAL_CXX0X__
204 void move(String &rhs);
205 #endif
206 };
207
208 class StringSumHelper : public String
209 {
210 public:
211 StringSumHelper(const String &s) : String(s) {}
212 StringSumHelper(const char *p) : String(p) {}
213 StringSumHelper(char c) : String(c) {}
214 StringSumHelper(unsigned char num) : String(num) {}
215 StringSumHelper(int num) : String(num) {}
216 StringSumHelper(unsigned int num) : String(num) {}
217 StringSumHelper(long num) : String(num) {}
218 StringSumHelper(unsigned long num) : String(num) {}
219 StringSumHelper(float num) : String(num) {}
220 StringSumHelper(double num) : String(num) {}
221 };
222
223 #endif // __cplusplus
224 #endif // String_class_h
@@ -0,0 +1,267
1 /* Copyright (c) 2002, 2004, 2010 Joerg Wunsch
2 Copyright (c) 2010 Gerben van den Broeke
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the
14 distribution.
15
16 * Neither the name of the copyright holders nor the names of
17 contributors may be used to endorse or promote products derived
18 from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34 /* $Id: malloc.c 2149 2010-06-09 20:45:37Z joerg_wunsch $ */
35
36 #include <stdlib.h>
37 #include "sectionname.h"
38 #include "stdlib_private.h"
39
40 #include <avr/io.h>
41
42 /*
43 * Exported interface:
44 *
45 * When extending the data segment, the allocator will not try to go
46 * beyond the current stack limit, decreased by __malloc_margin bytes.
47 * Thus, all possible stack frames of interrupt routines that could
48 * interrupt the current function, plus all further nested function
49 * calls must not require more stack space, or they'll risk to collide
50 * with the data segment.
51 */
52
53 /* May be changed by the user only before the first malloc() call. */
54
55 size_t __malloc_margin = 128;
56 char *__malloc_heap_start = &__heap_start;
57 char *__malloc_heap_end = &__heap_end;
58
59 char *__brkval;
60 struct __freelist *__flp;
61
62 ATTRIBUTE_CLIB_SECTION
63 void *
64 malloc(size_t len)
65 {
66 struct __freelist *fp1, *fp2, *sfp1, *sfp2;
67 char *cp;
68 size_t s, avail;
69
70 /*
71 * Our minimum chunk size is the size of a pointer (plus the
72 * size of the "sz" field, but we don't need to account for
73 * this), otherwise we could not possibly fit a freelist entry
74 * into the chunk later.
75 */
76 if (len < sizeof(struct __freelist) - sizeof(size_t))
77 len = sizeof(struct __freelist) - sizeof(size_t);
78
79 /*
80 * First, walk the free list and try finding a chunk that
81 * would match exactly. If we found one, we are done. While
82 * walking, note down the smallest chunk we found that would
83 * still fit the request -- we need it for step 2.
84 *
85 */
86 for (s = 0, fp1 = __flp, fp2 = 0;
87 fp1;
88 fp2 = fp1, fp1 = fp1->nx) {
89 if (fp1->sz < len)
90 continue;
91 if (fp1->sz == len) {
92 /*
93 * Found it. Disconnect the chunk from the
94 * freelist, and return it.
95 */
96 if (fp2)
97 fp2->nx = fp1->nx;
98 else
99 __flp = fp1->nx;
100 return &(fp1->nx);
101 }
102 else {
103 if (s == 0 || fp1->sz < s) {
104 /* this is the smallest chunk found so far */
105 s = fp1->sz;
106 sfp1 = fp1;
107 sfp2 = fp2;
108 }
109 }
110 }
111 /*
112 * Step 2: If we found a chunk on the freelist that would fit
113 * (but was too large), look it up again and use it, since it
114 * is our closest match now. Since the freelist entry needs
115 * to be split into two entries then, watch out that the
116 * difference between the requested size and the size of the
117 * chunk found is large enough for another freelist entry; if
118 * not, just enlarge the request size to what we have found,
119 * and use the entire chunk.
120 */
121 if (s) {
122 if (s - len < sizeof(struct __freelist)) {
123 /* Disconnect it from freelist and return it. */
124 if (sfp2)
125 sfp2->nx = sfp1->nx;
126 else
127 __flp = sfp1->nx;
128 return &(sfp1->nx);
129 }
130 /*
131 * Split them up. Note that we leave the first part
132 * as the new (smaller) freelist entry, and return the
133 * upper portion to the caller. This saves us the
134 * work to fix up the freelist chain; we just need to
135 * fixup the size of the current entry, and note down
136 * the size of the new chunk before returning it to
137 * the caller.
138 */
139 cp = (char *)sfp1;
140 s -= len;
141 cp += s;
142 sfp2 = (struct __freelist *)cp;
143 sfp2->sz = len;
144 sfp1->sz = s - sizeof(size_t);
145 return &(sfp2->nx);
146 }
147 /*
148 * Step 3: If the request could not be satisfied from a
149 * freelist entry, just prepare a new chunk. This means we
150 * need to obtain more memory first. The largest address just
151 * not allocated so far is remembered in the brkval variable.
152 * Under Unix, the "break value" was the end of the data
153 * segment as dynamically requested from the operating system.
154 * Since we don't have an operating system, just make sure
155 * that we don't collide with the stack.
156 */
157 if (__brkval == 0)
158 __brkval = __malloc_heap_start;
159 cp = __malloc_heap_end;
160 if (cp == 0)
161 cp = STACK_POINTER() - __malloc_margin;
162 if (cp <= __brkval)
163 /*
164 * Memory exhausted.
165 */
166 return 0;
167 avail = cp - __brkval;
168 /*
169 * Both tests below are needed to catch the case len >= 0xfffe.
170 */
171 if (avail >= len && avail >= len + sizeof(size_t)) {
172 fp1 = (struct __freelist *)__brkval;
173 __brkval += len + sizeof(size_t);
174 fp1->sz = len;
175 return &(fp1->nx);
176 }
177 /*
178 * Step 4: There's no help, just fail. :-/
179 */
180 return 0;
181 }
182
183
184 ATTRIBUTE_CLIB_SECTION
185 void
186 free(void *p)
187 {
188 struct __freelist *fp1, *fp2, *fpnew;
189 char *cp1, *cp2, *cpnew;
190
191 /* ISO C says free(NULL) must be a no-op */
192 if (p == 0)
193 return;
194
195 cpnew = p;
196 cpnew -= sizeof(size_t);
197 fpnew = (struct __freelist *)cpnew;
198 fpnew->nx = 0;
199
200 /*
201 * Trivial case first: if there's no freelist yet, our entry
202 * will be the only one on it. If this is the last entry, we
203 * can reduce __brkval instead.
204 */
205 if (__flp == 0) {
206 if ((char *)p + fpnew->sz == __brkval)
207 __brkval = cpnew;
208 else
209 __flp = fpnew;
210 return;
211 }
212
213 /*
214 * Now, find the position where our new entry belongs onto the
215 * freelist. Try to aggregate the chunk with adjacent chunks
216 * if possible.
217 */
218 for (fp1 = __flp, fp2 = 0;
219 fp1;
220 fp2 = fp1, fp1 = fp1->nx) {
221 if (fp1 < fpnew)
222 continue;
223 cp1 = (char *)fp1;
224 fpnew->nx = fp1;
225 if ((char *)&(fpnew->nx) + fpnew->sz == cp1) {
226 /* upper chunk adjacent, assimilate it */
227 fpnew->sz += fp1->sz + sizeof(size_t);
228 fpnew->nx = fp1->nx;
229 }
230 if (fp2 == 0) {
231 /* new head of freelist */
232 __flp = fpnew;
233 return;
234 }
235 break;
236 }
237 /*
238 * Note that we get here either if we hit the "break" above,
239 * or if we fell off the end of the loop. The latter means
240 * we've got a new topmost chunk. Either way, try aggregating
241 * with the lower chunk if possible.
242 */
243 fp2->nx = fpnew;
244 cp2 = (char *)&(fp2->nx);
245 if (cp2 + fp2->sz == cpnew) {
246 /* lower junk adjacent, merge */
247 fp2->sz += fpnew->sz + sizeof(size_t);
248 fp2->nx = fpnew->nx;
249 }
250 /*
251 * If there's a new topmost chunk, lower __brkval instead.
252 */
253 for (fp1 = __flp, fp2 = 0;
254 fp1->nx != 0;
255 fp2 = fp1, fp1 = fp1->nx)
256 /* advance to entry just before end of list */;
257 cp2 = (char *)&(fp1->nx);
258 if (cp2 + fp1->sz == __brkval) {
259 if (fp2 == NULL)
260 /* Freelist is empty now. */
261 __flp = NULL;
262 else
263 fp2->nx = NULL;
264 __brkval = cp2 - sizeof(size_t);
265 }
266 }
267
@@ -0,0 +1,150
1 /* Copyright (c) 2004, 2010 Joerg Wunsch
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in
12 the documentation and/or other materials provided with the
13 distribution.
14
15 * Neither the name of the copyright holders nor the names of
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30 */
31 /* $Id: realloc.c 2127 2010-06-07 14:49:37Z joerg_wunsch $ */
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include "sectionname.h"
36 #include "stdlib_private.h"
37
38 #include <avr/io.h>
39
40 ATTRIBUTE_CLIB_SECTION
41 void *
42 realloc(void *ptr, size_t len)
43 {
44 struct __freelist *fp1, *fp2, *fp3, *ofp3;
45 char *cp, *cp1;
46 void *memp;
47 size_t s, incr;
48
49 /* Trivial case, required by C standard. */
50 if (ptr == 0)
51 return malloc(len);
52
53 cp1 = (char *)ptr;
54 cp1 -= sizeof(size_t);
55 fp1 = (struct __freelist *)cp1;
56
57 cp = (char *)ptr + len; /* new next pointer */
58 if (cp < cp1)
59 /* Pointer wrapped across top of RAM, fail. */
60 return 0;
61
62 /*
63 * See whether we are growing or shrinking. When shrinking,
64 * we split off a chunk for the released portion, and call
65 * free() on it. Therefore, we can only shrink if the new
66 * size is at least sizeof(struct __freelist) smaller than the
67 * previous size.
68 */
69 if (len <= fp1->sz) {
70 /* The first test catches a possible unsigned int
71 * rollover condition. */
72 if (fp1->sz <= sizeof(struct __freelist) ||
73 len > fp1->sz - sizeof(struct __freelist))
74 return ptr;
75 fp2 = (struct __freelist *)cp;
76 fp2->sz = fp1->sz - len - sizeof(size_t);
77 fp1->sz = len;
78 free(&(fp2->nx));
79 return ptr;
80 }
81
82 /*
83 * If we get here, we are growing. First, see whether there
84 * is space in the free list on top of our current chunk.
85 */
86 incr = len - fp1->sz;
87 cp = (char *)ptr + fp1->sz;
88 fp2 = (struct __freelist *)cp;
89 for (s = 0, ofp3 = 0, fp3 = __flp;
90 fp3;
91 ofp3 = fp3, fp3 = fp3->nx) {
92 if (fp3 == fp2 && fp3->sz + sizeof(size_t) >= incr) {
93 /* found something that fits */
94 if (fp3->sz + sizeof(size_t) - incr > sizeof(struct __freelist)) {
95 /* split off a new freelist entry */
96 cp = (char *)ptr + len;
97 fp2 = (struct __freelist *)cp;
98 fp2->nx = fp3->nx;
99 fp2->sz = fp3->sz - incr;
100 fp1->sz = len;
101 } else {
102 /* it just fits, so use it entirely */
103 fp1->sz += fp3->sz + sizeof(size_t);
104 fp2 = fp3->nx;
105 }
106 if (ofp3)
107 ofp3->nx = fp2;
108 else
109 __flp = fp2;
110 return ptr;
111 }
112 /*
113 * Find the largest chunk on the freelist while
114 * walking it.
115 */
116 if (fp3->sz > s)
117 s = fp3->sz;
118 }
119 /*
120 * If we are the topmost chunk in memory, and there was no
121 * large enough chunk on the freelist that could be re-used
122 * (by a call to malloc() below), quickly extend the
123 * allocation area if possible, without need to copy the old
124 * data.
125 */
126 if (__brkval == (char *)ptr + fp1->sz && len > s) {
127 cp1 = __malloc_heap_end;
128 cp = (char *)ptr + len;
129 if (cp1 == 0)
130 cp1 = STACK_POINTER() - __malloc_margin;
131 if (cp < cp1) {
132 __brkval = cp;
133 fp1->sz = len;
134 return ptr;
135 }
136 /* If that failed, we are out of luck. */
137 return 0;
138 }
139
140 /*
141 * Call malloc() for a new chunk, then copy over the data, and
142 * release the old region.
143 */
144 if ((memp = malloc(len)) == 0)
145 return 0;
146 memcpy(memp, ptr, fp1->sz);
147 free(ptr);
148 return memp;
149 }
150
@@ -0,0 +1,49
1 /* Copyright (c) 2009 Atmel Corporation
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in
12 the documentation and/or other materials provided with the
13 distribution.
14
15 * Neither the name of the copyright holders nor the names of
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef __SECTIONNAME_H__
33 #define __SECTIONNAME_H__
34
35 /* Put all avr-libc functions in a common, unique sub-section name under .text. */
36
37 #define CLIB_SECTION .text.avr-libc
38 #define MLIB_SECTION .text.avr-libc.fplib
39
40 #define STR(x) _STR(x)
41 #define _STR(x) #x
42
43 #define ATTRIBUTE_CLIB_SECTION __attribute__ ((section (STR(CLIB_SECTION))))
44 #define ATTRIBUTE_MLIB_SECTION __attribute__ ((section (STR(MLIB_SECTION))))
45
46 #define ASSEMBLY_CLIB_SECTION .section CLIB_SECTION, "ax", @progbits
47 #define ASSEMBLY_MLIB_SECTION .section MLIB_SECTION, "ax", @progbits
48
49 #endif
@@ -0,0 +1,58
1 /* Copyright (c) 2004, Joerg Wunsch
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of the copyright holders nor the names of
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /* $Id: stdlib_private.h 1657 2008-03-24 17:11:08Z arcanum $ */
31
32 #include <inttypes.h>
33 #include <stdlib.h>
34 #include <avr/io.h>
35
36 #if !defined(__DOXYGEN__)
37
38 struct __freelist {
39 size_t sz;
40 struct __freelist *nx;
41 };
42
43 #endif
44
45 extern char *__brkval; /* first location not yet allocated */
46 extern struct __freelist *__flp; /* freelist pointer (head of freelist) */
47 extern size_t __malloc_margin; /* user-changeable before the first malloc() */
48 extern char *__malloc_heap_start;
49 extern char *__malloc_heap_end;
50
51 extern char __heap_start;
52 extern char __heap_end;
53
54 /* Needed for definition of AVR_STACK_POINTER_REG. */
55 #include <avr/io.h>
56
57 #define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG)
58
This diff has been collapsed as it changes many lines, (534 lines changed) Show them Hide them
@@ -0,0 +1,534
1 /*
2 binary.h - Definitions for binary constants
3 Copyright (c) 2006 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef Binary_h
21 #define Binary_h
22
23 #define B0 0
24 #define B00 0
25 #define B000 0
26 #define B0000 0
27 #define B00000 0
28 #define B000000 0
29 #define B0000000 0
30 #define B00000000 0
31 #define B1 1
32 #define B01 1
33 #define B001 1
34 #define B0001 1
35 #define B00001 1
36 #define B000001 1
37 #define B0000001 1
38 #define B00000001 1
39 #define B10 2
40 #define B010 2
41 #define B0010 2
42 #define B00010 2
43 #define B000010 2
44 #define B0000010 2
45 #define B00000010 2
46 #define B11 3
47 #define B011 3
48 #define B0011 3
49 #define B00011 3
50 #define B000011 3
51 #define B0000011 3
52 #define B00000011 3
53 #define B100 4
54 #define B0100 4
55 #define B00100 4
56 #define B000100 4
57 #define B0000100 4
58 #define B00000100 4
59 #define B101 5
60 #define B0101 5
61 #define B00101 5
62 #define B000101 5
63 #define B0000101 5
64 #define B00000101 5
65 #define B110 6
66 #define B0110 6
67 #define B00110 6
68 #define B000110 6
69 #define B0000110 6
70 #define B00000110 6
71 #define B111 7
72 #define B0111 7
73 #define B00111 7
74 #define B000111 7
75 #define B0000111 7
76 #define B00000111 7
77 #define B1000 8
78 #define B01000 8
79 #define B001000 8
80 #define B0001000 8
81 #define B00001000 8
82 #define B1001 9
83 #define B01001 9
84 #define B001001 9
85 #define B0001001 9
86 #define B00001001 9
87 #define B1010 10
88 #define B01010 10
89 #define B001010 10
90 #define B0001010 10
91 #define B00001010 10
92 #define B1011 11
93 #define B01011 11
94 #define B001011 11
95 #define B0001011 11
96 #define B00001011 11
97 #define B1100 12
98 #define B01100 12
99 #define B001100 12
100 #define B0001100 12
101 #define B00001100 12
102 #define B1101 13
103 #define B01101 13
104 #define B001101 13
105 #define B0001101 13
106 #define B00001101 13
107 #define B1110 14
108 #define B01110 14
109 #define B001110 14
110 #define B0001110 14
111 #define B00001110 14
112 #define B1111 15
113 #define B01111 15
114 #define B001111 15
115 #define B0001111 15
116 #define B00001111 15
117 #define B10000 16
118 #define B010000 16
119 #define B0010000 16
120 #define B00010000 16
121 #define B10001 17
122 #define B010001 17
123 #define B0010001 17
124 #define B00010001 17
125 #define B10010 18
126 #define B010010 18
127 #define B0010010 18
128 #define B00010010 18
129 #define B10011 19
130 #define B010011 19
131 #define B0010011 19
132 #define B00010011 19
133 #define B10100 20
134 #define B010100 20
135 #define B0010100 20
136 #define B00010100 20
137 #define B10101 21
138 #define B010101 21
139 #define B0010101 21
140 #define B00010101 21
141 #define B10110 22
142 #define B010110 22
143 #define B0010110 22
144 #define B00010110 22
145 #define B10111 23
146 #define B010111 23
147 #define B0010111 23
148 #define B00010111 23
149 #define B11000 24
150 #define B011000 24
151 #define B0011000 24
152 #define B00011000 24
153 #define B11001 25
154 #define B011001 25
155 #define B0011001 25
156 #define B00011001 25
157 #define B11010 26
158 #define B011010 26
159 #define B0011010 26
160 #define B00011010 26
161 #define B11011 27
162 #define B011011 27
163 #define B0011011 27
164 #define B00011011 27
165 #define B11100 28
166 #define B011100 28
167 #define B0011100 28
168 #define B00011100 28
169 #define B11101 29
170 #define B011101 29
171 #define B0011101 29
172 #define B00011101 29
173 #define B11110 30
174 #define B011110 30
175 #define B0011110 30
176 #define B00011110 30
177 #define B11111 31
178 #define B011111 31
179 #define B0011111 31
180 #define B00011111 31
181 #define B100000 32
182 #define B0100000 32
183 #define B00100000 32
184 #define B100001 33
185 #define B0100001 33
186 #define B00100001 33
187 #define B100010 34
188 #define B0100010 34
189 #define B00100010 34
190 #define B100011 35
191 #define B0100011 35
192 #define B00100011 35
193 #define B100100 36
194 #define B0100100 36
195 #define B00100100 36
196 #define B100101 37
197 #define B0100101 37
198 #define B00100101 37
199 #define B100110 38
200 #define B0100110 38
201 #define B00100110 38
202 #define B100111 39
203 #define B0100111 39
204 #define B00100111 39
205 #define B101000 40
206 #define B0101000 40
207 #define B00101000 40
208 #define B101001 41
209 #define B0101001 41
210 #define B00101001 41
211 #define B101010 42
212 #define B0101010 42
213 #define B00101010 42
214 #define B101011 43
215 #define B0101011 43
216 #define B00101011 43
217 #define B101100 44
218 #define B0101100 44
219 #define B00101100 44
220 #define B101101 45
221 #define B0101101 45
222 #define B00101101 45
223 #define B101110 46
224 #define B0101110 46
225 #define B00101110 46
226 #define B101111 47
227 #define B0101111 47
228 #define B00101111 47
229 #define B110000 48
230 #define B0110000 48
231 #define B00110000 48
232 #define B110001 49
233 #define B0110001 49
234 #define B00110001 49
235 #define B110010 50
236 #define B0110010 50
237 #define B00110010 50
238 #define B110011 51
239 #define B0110011 51
240 #define B00110011 51
241 #define B110100 52
242 #define B0110100 52
243 #define B00110100 52
244 #define B110101 53
245 #define B0110101 53
246 #define B00110101 53
247 #define B110110 54
248 #define B0110110 54
249 #define B00110110 54
250 #define B110111 55
251 #define B0110111 55
252 #define B00110111 55
253 #define B111000 56
254 #define B0111000 56
255 #define B00111000 56
256 #define B111001 57
257 #define B0111001 57
258 #define B00111001 57
259 #define B111010 58
260 #define B0111010 58
261 #define B00111010 58
262 #define B111011 59
263 #define B0111011 59
264 #define B00111011 59
265 #define B111100 60
266 #define B0111100 60
267 #define B00111100 60
268 #define B111101 61
269 #define B0111101 61
270 #define B00111101 61
271 #define B111110 62
272 #define B0111110 62
273 #define B00111110 62
274 #define B111111 63
275 #define B0111111 63
276 #define B00111111 63
277 #define B1000000 64
278 #define B01000000 64
279 #define B1000001 65
280 #define B01000001 65
281 #define B1000010 66
282 #define B01000010 66
283 #define B1000011 67
284 #define B01000011 67
285 #define B1000100 68
286 #define B01000100 68
287 #define B1000101 69
288 #define B01000101 69
289 #define B1000110 70
290 #define B01000110 70
291 #define B1000111 71
292 #define B01000111 71
293 #define B1001000 72
294 #define B01001000 72
295 #define B1001001 73
296 #define B01001001 73
297 #define B1001010 74
298 #define B01001010 74
299 #define B1001011 75
300 #define B01001011 75
301 #define B1001100 76
302 #define B01001100 76
303 #define B1001101 77
304 #define B01001101 77
305 #define B1001110 78
306 #define B01001110 78
307 #define B1001111 79
308 #define B01001111 79
309 #define B1010000 80
310 #define B01010000 80
311 #define B1010001 81
312 #define B01010001 81
313 #define B1010010 82
314 #define B01010010 82
315 #define B1010011 83
316 #define B01010011 83
317 #define B1010100 84
318 #define B01010100 84
319 #define B1010101 85
320 #define B01010101 85
321 #define B1010110 86
322 #define B01010110 86
323 #define B1010111 87
324 #define B01010111 87
325 #define B1011000 88
326 #define B01011000 88
327 #define B1011001 89
328 #define B01011001 89
329 #define B1011010 90
330 #define B01011010 90
331 #define B1011011 91
332 #define B01011011 91
333 #define B1011100 92
334 #define B01011100 92
335 #define B1011101 93
336 #define B01011101 93
337 #define B1011110 94
338 #define B01011110 94
339 #define B1011111 95
340 #define B01011111 95
341 #define B1100000 96
342 #define B01100000 96
343 #define B1100001 97
344 #define B01100001 97
345 #define B1100010 98
346 #define B01100010 98
347 #define B1100011 99
348 #define B01100011 99
349 #define B1100100 100
350 #define B01100100 100
351 #define B1100101 101
352 #define B01100101 101
353 #define B1100110 102
354 #define B01100110 102
355 #define B1100111 103
356 #define B01100111 103
357 #define B1101000 104
358 #define B01101000 104
359 #define B1101001 105
360 #define B01101001 105
361 #define B1101010 106
362 #define B01101010 106
363 #define B1101011 107
364 #define B01101011 107
365 #define B1101100 108
366 #define B01101100 108
367 #define B1101101 109
368 #define B01101101 109
369 #define B1101110 110
370 #define B01101110 110
371 #define B1101111 111
372 #define B01101111 111
373 #define B1110000 112
374 #define B01110000 112
375 #define B1110001 113
376 #define B01110001 113
377 #define B1110010 114
378 #define B01110010 114
379 #define B1110011 115
380 #define B01110011 115
381 #define B1110100 116
382 #define B01110100 116
383 #define B1110101 117
384 #define B01110101 117
385 #define B1110110 118
386 #define B01110110 118
387 #define B1110111 119
388 #define B01110111 119
389 #define B1111000 120
390 #define B01111000 120
391 #define B1111001 121
392 #define B01111001 121
393 #define B1111010 122
394 #define B01111010 122
395 #define B1111011 123
396 #define B01111011 123
397 #define B1111100 124
398 #define B01111100 124
399 #define B1111101 125
400 #define B01111101 125
401 #define B1111110 126
402 #define B01111110 126
403 #define B1111111 127
404 #define B01111111 127
405 #define B10000000 128
406 #define B10000001 129
407 #define B10000010 130
408 #define B10000011 131
409 #define B10000100 132
410 #define B10000101 133
411 #define B10000110 134
412 #define B10000111 135
413 #define B10001000 136
414 #define B10001001 137
415 #define B10001010 138
416 #define B10001011 139
417 #define B10001100 140
418 #define B10001101 141
419 #define B10001110 142
420 #define B10001111 143
421 #define B10010000 144
422 #define B10010001 145
423 #define B10010010 146
424 #define B10010011 147
425 #define B10010100 148
426 #define B10010101 149
427 #define B10010110 150
428 #define B10010111 151
429 #define B10011000 152
430 #define B10011001 153
431 #define B10011010 154
432 #define B10011011 155
433 #define B10011100 156
434 #define B10011101 157
435 #define B10011110 158
436 #define B10011111 159
437 #define B10100000 160
438 #define B10100001 161
439 #define B10100010 162
440 #define B10100011 163
441 #define B10100100 164
442 #define B10100101 165
443 #define B10100110 166
444 #define B10100111 167
445 #define B10101000 168
446 #define B10101001 169
447 #define B10101010 170
448 #define B10101011 171
449 #define B10101100 172
450 #define B10101101 173
451 #define B10101110 174
452 #define B10101111 175
453 #define B10110000 176
454 #define B10110001 177
455 #define B10110010 178
456 #define B10110011 179
457 #define B10110100 180
458 #define B10110101 181
459 #define B10110110 182
460 #define B10110111 183
461 #define B10111000 184
462 #define B10111001 185
463 #define B10111010 186
464 #define B10111011 187
465 #define B10111100 188
466 #define B10111101 189
467 #define B10111110 190
468 #define B10111111 191
469 #define B11000000 192
470 #define B11000001 193
471 #define B11000010 194
472 #define B11000011 195
473 #define B11000100 196
474 #define B11000101 197
475 #define B11000110 198
476 #define B11000111 199
477 #define B11001000 200
478 #define B11001001 201
479 #define B11001010 202
480 #define B11001011 203
481 #define B11001100 204
482 #define B11001101 205
483 #define B11001110 206
484 #define B11001111 207
485 #define B11010000 208
486 #define B11010001 209
487 #define B11010010 210
488 #define B11010011 211
489 #define B11010100 212
490 #define B11010101 213
491 #define B11010110 214
492 #define B11010111 215
493 #define B11011000 216
494 #define B11011001 217
495 #define B11011010 218
496 #define B11011011 219
497 #define B11011100 220
498 #define B11011101 221
499 #define B11011110 222
500 #define B11011111 223
501 #define B11100000 224
502 #define B11100001 225
503 #define B11100010 226
504 #define B11100011 227
505 #define B11100100 228
506 #define B11100101 229
507 #define B11100110 230
508 #define B11100111 231
509 #define B11101000 232
510 #define B11101001 233
511 #define B11101010 234
512 #define B11101011 235
513 #define B11101100 236
514 #define B11101101 237
515 #define B11101110 238
516 #define B11101111 239
517 #define B11110000 240
518 #define B11110001 241
519 #define B11110010 242
520 #define B11110011 243
521 #define B11110100 244
522 #define B11110101 245
523 #define B11110110 246
524 #define B11110111 247
525 #define B11111000 248
526 #define B11111001 249
527 #define B11111010 250
528 #define B11111011 251
529 #define B11111100 252
530 #define B11111101 253
531 #define B11111110 254
532 #define B11111111 255
533
534 #endif
@@ -0,0 +1,28
1 #include <new.h>
2
3 void * operator new(size_t size)
4 {
5 return malloc(size);
6 }
7
8 void * operator new[](size_t size)
9 {
10 return malloc(size);
11 }
12
13 void operator delete(void * ptr)
14 {
15 free(ptr);
16 }
17
18 void operator delete[](void * ptr)
19 {
20 free(ptr);
21 }
22
23 int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
24 void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
25 void __cxa_guard_abort (__guard *) {};
26
27 void __cxa_pure_virtual(void) {};
28
@@ -0,0 +1,24
1 /* Header to define new/delete operators as they aren't provided by avr-gcc by default
2 Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453
3 */
4
5 #ifndef NEW_H
6 #define NEW_H
7
8 #include <stdlib.h>
9
10 void * operator new(size_t size);
11 void * operator new[](size_t size);
12 void operator delete(void * ptr);
13 void operator delete[](void * ptr);
14
15 __extension__ typedef int __guard __attribute__((mode (__DI__)));
16
17 extern "C" int __cxa_guard_acquire(__guard *);
18 extern "C" void __cxa_guard_release (__guard *);
19 extern "C" void __cxa_guard_abort (__guard *);
20
21 extern "C" void __cxa_pure_virtual(void);
22
23 #endif
24
@@ -0,0 +1,389
1 /*
2 pins_arduino.h - Pin definition functions for Arduino
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2007 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
23 */
24
25 #ifndef Pins_Arduino_h
26 #define Pins_Arduino_h
27
28 #include <avr/pgmspace.h>
29
30 #define NUM_DIGITAL_PINS 70
31 #define NUM_ANALOG_INPUTS 16
32 #define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1)
33 #define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46))
34
35 static const uint8_t SS = 53;
36 static const uint8_t MOSI = 51;
37 static const uint8_t MISO = 50;
38 static const uint8_t SCK = 52;
39
40 static const uint8_t SDA = 20;
41 static const uint8_t SCL = 21;
42 #define LED_BUILTIN 13
43
44 static const uint8_t A0 = 54;
45 static const uint8_t A1 = 55;
46 static const uint8_t A2 = 56;
47 static const uint8_t A3 = 57;
48 static const uint8_t A4 = 58;
49 static const uint8_t A5 = 59;
50 static const uint8_t A6 = 60;
51 static const uint8_t A7 = 61;
52 static const uint8_t A8 = 62;
53 static const uint8_t A9 = 63;
54 static const uint8_t A10 = 64;
55 static const uint8_t A11 = 65;
56 static const uint8_t A12 = 66;
57 static const uint8_t A13 = 67;
58 static const uint8_t A14 = 68;
59 static const uint8_t A15 = 69;
60
61 // A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
62 // Only pins available for RECEIVE (TRANSMIT can be on any pin):
63 // (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
64 // Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
65
66 #define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \
67 (((p) >= 50) && ((p) <= 53)) || \
68 (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )
69
70 #define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \
71 ( (((p) >= 62) && ((p) <= 69)) ? 2 : \
72 0 ) )
73
74 #define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \
75 ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \
76 ((uint8_t *)0) ) )
77
78 #define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \
79 ( ((p) == 50) ? 3 : \
80 ( ((p) == 51) ? 2 : \
81 ( ((p) == 52) ? 1 : \
82 ( ((p) == 53) ? 0 : \
83 ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \
84 0 ) ) ) ) ) )
85
86 #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : ((p) >= 18 && (p) <= 21 ? 23 - (p) : NOT_AN_INTERRUPT)))
87
88 #ifdef ARDUINO_MAIN
89
90 const uint16_t PROGMEM port_to_mode_PGM[] = {
91 NOT_A_PORT,
92 (uint16_t) &DDRA,
93 (uint16_t) &DDRB,
94 (uint16_t) &DDRC,
95 (uint16_t) &DDRD,
96 (uint16_t) &DDRE,
97 (uint16_t) &DDRF,
98 (uint16_t) &DDRG,
99 (uint16_t) &DDRH,
100 NOT_A_PORT,
101 (uint16_t) &DDRJ,
102 (uint16_t) &DDRK,
103 (uint16_t) &DDRL,
104 };
105
106 const uint16_t PROGMEM port_to_output_PGM[] = {
107 NOT_A_PORT,
108 (uint16_t) &PORTA,
109 (uint16_t) &PORTB,
110 (uint16_t) &PORTC,
111 (uint16_t) &PORTD,
112 (uint16_t) &PORTE,
113 (uint16_t) &PORTF,
114 (uint16_t) &PORTG,
115 (uint16_t) &PORTH,
116 NOT_A_PORT,
117 (uint16_t) &PORTJ,
118 (uint16_t) &PORTK,
119 (uint16_t) &PORTL,
120 };
121
122 const uint16_t PROGMEM port_to_input_PGM[] = {
123 NOT_A_PIN,
124 (uint16_t) &PINA,
125 (uint16_t) &PINB,
126 (uint16_t) &PINC,
127 (uint16_t) &PIND,
128 (uint16_t) &PINE,
129 (uint16_t) &PINF,
130 (uint16_t) &PING,
131 (uint16_t) &PINH,
132 NOT_A_PIN,
133 (uint16_t) &PINJ,
134 (uint16_t) &PINK,
135 (uint16_t) &PINL,
136 };
137
138 const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
139 // PORTLIST
140 // -------------------------------------------
141 PE , // PE 0 ** 0 ** USART0_RX
142 PE , // PE 1 ** 1 ** USART0_TX
143 PE , // PE 4 ** 2 ** PWM2
144 PE , // PE 5 ** 3 ** PWM3
145 PG , // PG 5 ** 4 ** PWM4
146 PE , // PE 3 ** 5 ** PWM5
147 PH , // PH 3 ** 6 ** PWM6
148 PH , // PH 4 ** 7 ** PWM7
149 PH , // PH 5 ** 8 ** PWM8
150 PH , // PH 6 ** 9 ** PWM9
151 PB , // PB 4 ** 10 ** PWM10
152 PB , // PB 5 ** 11 ** PWM11
153 PB , // PB 6 ** 12 ** PWM12
154 PB , // PB 7 ** 13 ** PWM13
155 PJ , // PJ 1 ** 14 ** USART3_TX
156 PJ , // PJ 0 ** 15 ** USART3_RX
157 PH , // PH 1 ** 16 ** USART2_TX
158 PH , // PH 0 ** 17 ** USART2_RX
159 PD , // PD 3 ** 18 ** USART1_TX
160 PD , // PD 2 ** 19 ** USART1_RX
161 PD , // PD 1 ** 20 ** I2C_SDA
162 PD , // PD 0 ** 21 ** I2C_SCL
163 PA , // PA 0 ** 22 ** D22
164 PA , // PA 1 ** 23 ** D23
165 PA , // PA 2 ** 24 ** D24
166 PA , // PA 3 ** 25 ** D25
167 PA , // PA 4 ** 26 ** D26
168 PA , // PA 5 ** 27 ** D27
169 PA , // PA 6 ** 28 ** D28
170 PA , // PA 7 ** 29 ** D29
171 PC , // PC 7 ** 30 ** D30
172 PC , // PC 6 ** 31 ** D31
173 PC , // PC 5 ** 32 ** D32
174 PC , // PC 4 ** 33 ** D33
175 PC , // PC 3 ** 34 ** D34
176 PC , // PC 2 ** 35 ** D35
177 PC , // PC 1 ** 36 ** D36
178 PC , // PC 0 ** 37 ** D37
179 PD , // PD 7 ** 38 ** D38
180 PG , // PG 2 ** 39 ** D39
181 PG , // PG 1 ** 40 ** D40
182 PG , // PG 0 ** 41 ** D41
183 PL , // PL 7 ** 42 ** D42
184 PL , // PL 6 ** 43 ** D43
185 PL , // PL 5 ** 44 ** D44
186 PL , // PL 4 ** 45 ** D45
187 PL , // PL 3 ** 46 ** D46
188 PL , // PL 2 ** 47 ** D47
189 PL , // PL 1 ** 48 ** D48
190 PL , // PL 0 ** 49 ** D49
191 PB , // PB 3 ** 50 ** SPI_MISO
192 PB , // PB 2 ** 51 ** SPI_MOSI
193 PB , // PB 1 ** 52 ** SPI_SCK
194 PB , // PB 0 ** 53 ** SPI_SS
195 PF , // PF 0 ** 54 ** A0
196 PF , // PF 1 ** 55 ** A1
197 PF , // PF 2 ** 56 ** A2
198 PF , // PF 3 ** 57 ** A3
199 PF , // PF 4 ** 58 ** A4
200 PF , // PF 5 ** 59 ** A5
201 PF , // PF 6 ** 60 ** A6
202 PF , // PF 7 ** 61 ** A7
203 PK , // PK 0 ** 62 ** A8
204 PK , // PK 1 ** 63 ** A9
205 PK , // PK 2 ** 64 ** A10
206 PK , // PK 3 ** 65 ** A11
207 PK , // PK 4 ** 66 ** A12
208 PK , // PK 5 ** 67 ** A13
209 PK , // PK 6 ** 68 ** A14
210 PK , // PK 7 ** 69 ** A15
211 };
212
213 const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
214 // PIN IN PORT
215 // -------------------------------------------
216 _BV( 0 ) , // PE 0 ** 0 ** USART0_RX
217 _BV( 1 ) , // PE 1 ** 1 ** USART0_TX
218 _BV( 4 ) , // PE 4 ** 2 ** PWM2
219 _BV( 5 ) , // PE 5 ** 3 ** PWM3
220 _BV( 5 ) , // PG 5 ** 4 ** PWM4
221 _BV( 3 ) , // PE 3 ** 5 ** PWM5
222 _BV( 3 ) , // PH 3 ** 6 ** PWM6
223 _BV( 4 ) , // PH 4 ** 7 ** PWM7
224 _BV( 5 ) , // PH 5 ** 8 ** PWM8
225 _BV( 6 ) , // PH 6 ** 9 ** PWM9
226 _BV( 4 ) , // PB 4 ** 10 ** PWM10
227 _BV( 5 ) , // PB 5 ** 11 ** PWM11
228 _BV( 6 ) , // PB 6 ** 12 ** PWM12
229 _BV( 7 ) , // PB 7 ** 13 ** PWM13
230 _BV( 1 ) , // PJ 1 ** 14 ** USART3_TX
231 _BV( 0 ) , // PJ 0 ** 15 ** USART3_RX
232 _BV( 1 ) , // PH 1 ** 16 ** USART2_TX
233 _BV( 0 ) , // PH 0 ** 17 ** USART2_RX
234 _BV( 3 ) , // PD 3 ** 18 ** USART1_TX
235 _BV( 2 ) , // PD 2 ** 19 ** USART1_RX
236 _BV( 1 ) , // PD 1 ** 20 ** I2C_SDA
237 _BV( 0 ) , // PD 0 ** 21 ** I2C_SCL
238 _BV( 0 ) , // PA 0 ** 22 ** D22
239 _BV( 1 ) , // PA 1 ** 23 ** D23
240 _BV( 2 ) , // PA 2 ** 24 ** D24
241 _BV( 3 ) , // PA 3 ** 25 ** D25
242 _BV( 4 ) , // PA 4 ** 26 ** D26
243 _BV( 5 ) , // PA 5 ** 27 ** D27
244 _BV( 6 ) , // PA 6 ** 28 ** D28
245 _BV( 7 ) , // PA 7 ** 29 ** D29
246 _BV( 7 ) , // PC 7 ** 30 ** D30
247 _BV( 6 ) , // PC 6 ** 31 ** D31
248 _BV( 5 ) , // PC 5 ** 32 ** D32
249 _BV( 4 ) , // PC 4 ** 33 ** D33
250 _BV( 3 ) , // PC 3 ** 34 ** D34
251 _BV( 2 ) , // PC 2 ** 35 ** D35
252 _BV( 1 ) , // PC 1 ** 36 ** D36
253 _BV( 0 ) , // PC 0 ** 37 ** D37
254 _BV( 7 ) , // PD 7 ** 38 ** D38
255 _BV( 2 ) , // PG 2 ** 39 ** D39
256 _BV( 1 ) , // PG 1 ** 40 ** D40
257 _BV( 0 ) , // PG 0 ** 41 ** D41
258 _BV( 7 ) , // PL 7 ** 42 ** D42
259 _BV( 6 ) , // PL 6 ** 43 ** D43
260 _BV( 5 ) , // PL 5 ** 44 ** D44
261 _BV( 4 ) , // PL 4 ** 45 ** D45
262 _BV( 3 ) , // PL 3 ** 46 ** D46
263 _BV( 2 ) , // PL 2 ** 47 ** D47
264 _BV( 1 ) , // PL 1 ** 48 ** D48
265 _BV( 0 ) , // PL 0 ** 49 ** D49
266 _BV( 3 ) , // PB 3 ** 50 ** SPI_MISO
267 _BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI
268 _BV( 1 ) , // PB 1 ** 52 ** SPI_SCK
269 _BV( 0 ) , // PB 0 ** 53 ** SPI_SS
270 _BV( 0 ) , // PF 0 ** 54 ** A0
271 _BV( 1 ) , // PF 1 ** 55 ** A1
272 _BV( 2 ) , // PF 2 ** 56 ** A2
273 _BV( 3 ) , // PF 3 ** 57 ** A3
274 _BV( 4 ) , // PF 4 ** 58 ** A4
275 _BV( 5 ) , // PF 5 ** 59 ** A5
276 _BV( 6 ) , // PF 6 ** 60 ** A6
277 _BV( 7 ) , // PF 7 ** 61 ** A7
278 _BV( 0 ) , // PK 0 ** 62 ** A8
279 _BV( 1 ) , // PK 1 ** 63 ** A9
280 _BV( 2 ) , // PK 2 ** 64 ** A10
281 _BV( 3 ) , // PK 3 ** 65 ** A11
282 _BV( 4 ) , // PK 4 ** 66 ** A12
283 _BV( 5 ) , // PK 5 ** 67 ** A13
284 _BV( 6 ) , // PK 6 ** 68 ** A14
285 _BV( 7 ) , // PK 7 ** 69 ** A15
286 };
287
288 const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
289 // TIMERS
290 // -------------------------------------------
291 NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX
292 NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX
293 TIMER3B , // PE 4 ** 2 ** PWM2
294 TIMER3C , // PE 5 ** 3 ** PWM3
295 TIMER0B , // PG 5 ** 4 ** PWM4
296 TIMER3A , // PE 3 ** 5 ** PWM5
297 TIMER4A , // PH 3 ** 6 ** PWM6
298 TIMER4B , // PH 4 ** 7 ** PWM7
299 TIMER4C , // PH 5 ** 8 ** PWM8
300 TIMER2B , // PH 6 ** 9 ** PWM9
301 TIMER2A , // PB 4 ** 10 ** PWM10
302 TIMER1A , // PB 5 ** 11 ** PWM11
303 TIMER1B , // PB 6 ** 12 ** PWM12
304 TIMER0A , // PB 7 ** 13 ** PWM13
305 NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX
306 NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX
307 NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX
308 NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX
309 NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX
310 NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX
311 NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA
312 NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL
313 NOT_ON_TIMER , // PA 0 ** 22 ** D22
314 NOT_ON_TIMER , // PA 1 ** 23 ** D23
315 NOT_ON_TIMER , // PA 2 ** 24 ** D24
316 NOT_ON_TIMER , // PA 3 ** 25 ** D25
317 NOT_ON_TIMER , // PA 4 ** 26 ** D26
318 NOT_ON_TIMER , // PA 5 ** 27 ** D27
319 NOT_ON_TIMER , // PA 6 ** 28 ** D28
320 NOT_ON_TIMER , // PA 7 ** 29 ** D29
321 NOT_ON_TIMER , // PC 7 ** 30 ** D30
322 NOT_ON_TIMER , // PC 6 ** 31 ** D31
323 NOT_ON_TIMER , // PC 5 ** 32 ** D32
324 NOT_ON_TIMER , // PC 4 ** 33 ** D33
325 NOT_ON_TIMER , // PC 3 ** 34 ** D34
326 NOT_ON_TIMER , // PC 2 ** 35 ** D35
327 NOT_ON_TIMER , // PC 1 ** 36 ** D36
328 NOT_ON_TIMER , // PC 0 ** 37 ** D37
329 NOT_ON_TIMER , // PD 7 ** 38 ** D38
330 NOT_ON_TIMER , // PG 2 ** 39 ** D39
331 NOT_ON_TIMER , // PG 1 ** 40 ** D40
332 NOT_ON_TIMER , // PG 0 ** 41 ** D41
333 NOT_ON_TIMER , // PL 7 ** 42 ** D42
334 NOT_ON_TIMER , // PL 6 ** 43 ** D43
335 TIMER5C , // PL 5 ** 44 ** D44
336 TIMER5B , // PL 4 ** 45 ** D45
337 TIMER5A , // PL 3 ** 46 ** D46
338 NOT_ON_TIMER , // PL 2 ** 47 ** D47
339 NOT_ON_TIMER , // PL 1 ** 48 ** D48
340 NOT_ON_TIMER , // PL 0 ** 49 ** D49
341 NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO
342 NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI
343 NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK
344 NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS
345 NOT_ON_TIMER , // PF 0 ** 54 ** A0
346 NOT_ON_TIMER , // PF 1 ** 55 ** A1
347 NOT_ON_TIMER , // PF 2 ** 56 ** A2
348 NOT_ON_TIMER , // PF 3 ** 57 ** A3
349 NOT_ON_TIMER , // PF 4 ** 58 ** A4
350 NOT_ON_TIMER , // PF 5 ** 59 ** A5
351 NOT_ON_TIMER , // PF 6 ** 60 ** A6
352 NOT_ON_TIMER , // PF 7 ** 61 ** A7
353 NOT_ON_TIMER , // PK 0 ** 62 ** A8
354 NOT_ON_TIMER , // PK 1 ** 63 ** A9
355 NOT_ON_TIMER , // PK 2 ** 64 ** A10
356 NOT_ON_TIMER , // PK 3 ** 65 ** A11
357 NOT_ON_TIMER , // PK 4 ** 66 ** A12
358 NOT_ON_TIMER , // PK 5 ** 67 ** A13
359 NOT_ON_TIMER , // PK 6 ** 68 ** A14
360 NOT_ON_TIMER , // PK 7 ** 69 ** A15
361 };
362
363 #endif
364
365 // These serial port names are intended to allow libraries and architecture-neutral
366 // sketches to automatically default to the correct port name for a particular type
367 // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
368 // the first hardware serial port whose RX/TX pins are not dedicated to another use.
369 //
370 // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
371 //
372 // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
373 //
374 // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
375 //
376 // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
377 //
378 // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
379 // pins are NOT connected to anything by default.
380 #define SERIAL_PORT_MONITOR Serial
381 #define SERIAL_PORT_HARDWARE Serial
382 #define SERIAL_PORT_HARDWARE1 Serial1
383 #define SERIAL_PORT_HARDWARE2 Serial2
384 #define SERIAL_PORT_HARDWARE3 Serial3
385 #define SERIAL_PORT_HARDWARE_OPEN Serial1
386 #define SERIAL_PORT_HARDWARE_OPEN1 Serial2
387 #define SERIAL_PORT_HARDWARE_OPEN2 Serial3
388
389 #endif
This diff has been collapsed as it changes many lines, (527 lines changed) Show them Hide them
@@ -0,0 +1,527
1 /*
2 twi.c - TWI/I2C library for Wiring & Arduino
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
20 */
21
22 #include <math.h>
23 #include <stdlib.h>
24 #include <inttypes.h>
25 #include <avr/io.h>
26 #include <avr/interrupt.h>
27 #include <compat/twi.h>
28 #include "Arduino.h" // for digitalWrite
29
30 #ifndef cbi
31 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
32 #endif
33
34 #ifndef sbi
35 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
36 #endif
37
38 #include "pins_arduino.h"
39 #include "twi.h"
40
41 static volatile uint8_t twi_state;
42 static volatile uint8_t twi_slarw;
43 static volatile uint8_t twi_sendStop; // should the transaction end with a stop
44 static volatile uint8_t twi_inRepStart; // in the middle of a repeated start
45
46 static void (*twi_onSlaveTransmit)(void);
47 static void (*twi_onSlaveReceive)(uint8_t*, int);
48
49 static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
50 static volatile uint8_t twi_masterBufferIndex;
51 static volatile uint8_t twi_masterBufferLength;
52
53 static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
54 static volatile uint8_t twi_txBufferIndex;
55 static volatile uint8_t twi_txBufferLength;
56
57 static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
58 static volatile uint8_t twi_rxBufferIndex;
59
60 static volatile uint8_t twi_error;
61
62 /*
63 * Function twi_init
64 * Desc readys twi pins and sets twi bitrate
65 * Input none
66 * Output none
67 */
68 void twi_init(void)
69 {
70 // initialize state
71 twi_state = TWI_READY;
72 twi_sendStop = true; // default value
73 twi_inRepStart = false;
74
75 // activate internal pullups for twi.
76 digitalWrite(SDA, 1);
77 digitalWrite(SCL, 1);
78
79 // initialize twi prescaler and bit rate
80 cbi(TWSR, TWPS0);
81 cbi(TWSR, TWPS1);
82 TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
83
84 /* twi bit rate formula from atmega128 manual pg 204
85 SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
86 note: TWBR should be 10 or higher for master mode
87 It is 72 for a 16mhz Wiring board with 100kHz TWI */
88
89 // enable twi module, acks, and twi interrupt
90 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
91 }
92
93 /*
94 * Function twi_slaveInit
95 * Desc sets slave address and enables interrupt
96 * Input none
97 * Output none
98 */
99 void twi_setAddress(uint8_t address)
100 {
101 // set twi slave address (skip over TWGCE bit)
102 TWAR = address << 1;
103 }
104
105 /*
106 * Function twi_readFrom
107 * Desc attempts to become twi bus master and read a
108 * series of bytes from a device on the bus
109 * Input address: 7bit i2c device address
110 * data: pointer to byte array
111 * length: number of bytes to read into array
112 * sendStop: Boolean indicating whether to send a stop at the end
113 * Output number of bytes read
114 */
115 uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
116 {
117 uint8_t i;
118
119 // ensure data will fit into buffer
120 if(TWI_BUFFER_LENGTH < length){
121 return 0;
122 }
123
124 // wait until twi is ready, become master receiver
125 while(TWI_READY != twi_state){
126 continue;
127 }
128 twi_state = TWI_MRX;
129 twi_sendStop = sendStop;
130 // reset error state (0xFF.. no error occured)
131 twi_error = 0xFF;
132
133 // initialize buffer iteration vars
134 twi_masterBufferIndex = 0;
135 twi_masterBufferLength = length-1; // This is not intuitive, read on...
136 // On receive, the previously configured ACK/NACK setting is transmitted in
137 // response to the received byte before the interrupt is signalled.
138 // Therefor we must actually set NACK when the _next_ to last byte is
139 // received, causing that NACK to be sent in response to receiving the last
140 // expected byte of data.
141
142 // build sla+w, slave device address + w bit
143 twi_slarw = TW_READ;
144 twi_slarw |= address << 1;
145
146 if (true == twi_inRepStart) {
147 // if we're in the repeated start state, then we've already sent the start,
148 // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
149 // We need to remove ourselves from the repeated start state before we enable interrupts,
150 // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
151 // up. Also, don't enable the START interrupt. There may be one pending from the
152 // repeated start that we sent outselves, and that would really confuse things.
153 twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
154 TWDR = twi_slarw;
155 TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
156 }
157 else
158 // send start condition
159 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
160
161 // wait for read operation to complete
162 while(TWI_MRX == twi_state){
163 continue;
164 }
165
166 if (twi_masterBufferIndex < length)
167 length = twi_masterBufferIndex;
168
169 // copy twi buffer to data
170 for(i = 0; i < length; ++i){
171 data[i] = twi_masterBuffer[i];
172 }
173
174 return length;
175 }
176
177 /*
178 * Function twi_writeTo
179 * Desc attempts to become twi bus master and write a
180 * series of bytes to a device on the bus
181 * Input address: 7bit i2c device address
182 * data: pointer to byte array
183 * length: number of bytes in array
184 * wait: boolean indicating to wait for write or not
185 * sendStop: boolean indicating whether or not to send a stop at the end
186 * Output 0 .. success
187 * 1 .. length to long for buffer
188 * 2 .. address send, NACK received
189 * 3 .. data send, NACK received
190 * 4 .. other twi error (lost bus arbitration, bus error, ..)
191 */
192 uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
193 {
194 uint8_t i;
195
196 // ensure data will fit into buffer
197 if(TWI_BUFFER_LENGTH < length){
198 return 1;
199 }
200
201 // wait until twi is ready, become master transmitter
202 while(TWI_READY != twi_state){
203 continue;
204 }
205 twi_state = TWI_MTX;
206 twi_sendStop = sendStop;
207 // reset error state (0xFF.. no error occured)
208 twi_error = 0xFF;
209
210 // initialize buffer iteration vars
211 twi_masterBufferIndex = 0;
212 twi_masterBufferLength = length;
213
214 // copy data to twi buffer
215 for(i = 0; i < length; ++i){
216 twi_masterBuffer[i] = data[i];
217 }
218
219 // build sla+w, slave device address + w bit
220 twi_slarw = TW_WRITE;
221 twi_slarw |= address << 1;
222
223 // if we're in a repeated start, then we've already sent the START
224 // in the ISR. Don't do it again.
225 //
226 if (true == twi_inRepStart) {
227 // if we're in the repeated start state, then we've already sent the start,
228 // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
229 // We need to remove ourselves from the repeated start state before we enable interrupts,
230 // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
231 // up. Also, don't enable the START interrupt. There may be one pending from the
232 // repeated start that we sent outselves, and that would really confuse things.
233 twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
234 TWDR = twi_slarw;
235 TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
236 }
237 else
238 // send start condition
239 TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
240
241 // wait for write operation to complete
242 while(wait && (TWI_MTX == twi_state)){
243 continue;
244 }
245
246 if (twi_error == 0xFF)
247 return 0; // success
248 else if (twi_error == TW_MT_SLA_NACK)
249 return 2; // error: address send, nack received
250 else if (twi_error == TW_MT_DATA_NACK)
251 return 3; // error: data send, nack received
252 else
253 return 4; // other twi error
254 }
255
256 /*
257 * Function twi_transmit
258 * Desc fills slave tx buffer with data
259 * must be called in slave tx event callback
260 * Input data: pointer to byte array
261 * length: number of bytes in array
262 * Output 1 length too long for buffer
263 * 2 not slave transmitter
264 * 0 ok
265 */
266 uint8_t twi_transmit(const uint8_t* data, uint8_t length)
267 {
268 uint8_t i;
269
270 // ensure data will fit into buffer
271 if(TWI_BUFFER_LENGTH < length){
272 return 1;
273 }
274
275 // ensure we are currently a slave transmitter
276 if(TWI_STX != twi_state){
277 return 2;
278 }
279
280 // set length and copy data into tx buffer
281 twi_txBufferLength = length;
282 for(i = 0; i < length; ++i){
283 twi_txBuffer[i] = data[i];
284 }
285
286 return 0;
287 }
288
289 /*
290 * Function twi_attachSlaveRxEvent
291 * Desc sets function called before a slave read operation
292 * Input function: callback function to use
293 * Output none
294 */
295 void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )
296 {
297 twi_onSlaveReceive = function;
298 }
299
300 /*
301 * Function twi_attachSlaveTxEvent
302 * Desc sets function called before a slave write operation
303 * Input function: callback function to use
304 * Output none
305 */
306 void twi_attachSlaveTxEvent( void (*function)(void) )
307 {
308 twi_onSlaveTransmit = function;
309 }
310
311 /*
312 * Function twi_reply
313 * Desc sends byte or readys receive line
314 * Input ack: byte indicating to ack or to nack
315 * Output none
316 */
317 void twi_reply(uint8_t ack)
318 {
319 // transmit master read ready signal, with or without ack
320 if(ack){
321 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
322 }else{
323 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
324 }
325 }
326
327 /*
328 * Function twi_stop
329 * Desc relinquishes bus master status
330 * Input none
331 * Output none
332 */
333 void twi_stop(void)
334 {
335 // send stop condition
336 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
337
338 // wait for stop condition to be exectued on bus
339 // TWINT is not set after a stop condition!
340 while(TWCR & _BV(TWSTO)){
341 continue;
342 }
343
344 // update twi state
345 twi_state = TWI_READY;
346 }
347
348 /*
349 * Function twi_releaseBus
350 * Desc releases bus control
351 * Input none
352 * Output none
353 */
354 void twi_releaseBus(void)
355 {
356 // release bus
357 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
358
359 // update twi state
360 twi_state = TWI_READY;
361 }
362
363 ISR(TWI_vect)
364 {
365 switch(TW_STATUS){
366 // All Master
367 case TW_START: // sent start condition
368 case TW_REP_START: // sent repeated start condition
369 // copy device address and r/w bit to output register and ack
370 TWDR = twi_slarw;
371 twi_reply(1);
372 break;
373
374 // Master Transmitter
375 case TW_MT_SLA_ACK: // slave receiver acked address
376 case TW_MT_DATA_ACK: // slave receiver acked data
377 // if there is data to send, send it, otherwise stop
378 if(twi_masterBufferIndex < twi_masterBufferLength){
379 // copy data to output register and ack
380 TWDR = twi_masterBuffer[twi_masterBufferIndex++];
381 twi_reply(1);
382 }else{
383 if (twi_sendStop)
384 twi_stop();
385 else {
386 twi_inRepStart = true; // we're gonna send the START
387 // don't enable the interrupt. We'll generate the start, but we
388 // avoid handling the interrupt until we're in the next transaction,
389 // at the point where we would normally issue the start.
390 TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
391 twi_state = TWI_READY;
392 }
393 }
394 break;
395 case TW_MT_SLA_NACK: // address sent, nack received
396 twi_error = TW_MT_SLA_NACK;
397 twi_stop();
398 break;
399 case TW_MT_DATA_NACK: // data sent, nack received
400 twi_error = TW_MT_DATA_NACK;
401 twi_stop();
402 break;
403 case TW_MT_ARB_LOST: // lost bus arbitration
404 twi_error = TW_MT_ARB_LOST;
405 twi_releaseBus();
406 break;
407
408 // Master Receiver
409 case TW_MR_DATA_ACK: // data received, ack sent
410 // put byte into buffer
411 twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
412 case TW_MR_SLA_ACK: // address sent, ack received
413 // ack if more bytes are expected, otherwise nack
414 if(twi_masterBufferIndex < twi_masterBufferLength){
415 twi_reply(1);
416 }else{
417 twi_reply(0);
418 }
419 break;
420 case TW_MR_DATA_NACK: // data received, nack sent
421 // put final byte into buffer
422 twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
423 if (twi_sendStop)
424 twi_stop();
425 else {
426 twi_inRepStart = true; // we're gonna send the START
427 // don't enable the interrupt. We'll generate the start, but we
428 // avoid handling the interrupt until we're in the next transaction,
429 // at the point where we would normally issue the start.
430 TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
431 twi_state = TWI_READY;
432 }
433 break;
434 case TW_MR_SLA_NACK: // address sent, nack received
435 twi_stop();
436 break;
437 // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case
438
439 // Slave Receiver
440 case TW_SR_SLA_ACK: // addressed, returned ack
441 case TW_SR_GCALL_ACK: // addressed generally, returned ack
442 case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
443 case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
444 // enter slave receiver mode
445 twi_state = TWI_SRX;
446 // indicate that rx buffer can be overwritten and ack
447 twi_rxBufferIndex = 0;
448 twi_reply(1);
449 break;
450 case TW_SR_DATA_ACK: // data received, returned ack
451 case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
452 // if there is still room in the rx buffer
453 if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
454 // put byte in buffer and ack
455 twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
456 twi_reply(1);
457 }else{
458 // otherwise nack
459 twi_reply(0);
460 }
461 break;
462 case TW_SR_STOP: // stop or repeated start condition received
463 // put a null char after data if there's room
464 if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
465 twi_rxBuffer[twi_rxBufferIndex] = '\0';
466 }
467 // sends ack and stops interface for clock stretching
468 twi_stop();
469 // callback to user defined callback
470 twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
471 // since we submit rx buffer to "wire" library, we can reset it
472 twi_rxBufferIndex = 0;
473 // ack future responses and leave slave receiver state
474 twi_releaseBus();
475 break;
476 case TW_SR_DATA_NACK: // data received, returned nack
477 case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
478 // nack back at master
479 twi_reply(0);
480 break;
481
482 // Slave Transmitter
483 case TW_ST_SLA_ACK: // addressed, returned ack
484 case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
485 // enter slave transmitter mode
486 twi_state = TWI_STX;
487 // ready the tx buffer index for iteration
488 twi_txBufferIndex = 0;
489 // set tx buffer length to be zero, to verify if user changes it
490 twi_txBufferLength = 0;
491 // request for txBuffer to be filled and length to be set
492 // note: user must call twi_transmit(bytes, length) to do this
493 twi_onSlaveTransmit();
494 // if they didn't change buffer & length, initialize it
495 if(0 == twi_txBufferLength){
496 twi_txBufferLength = 1;
497 twi_txBuffer[0] = 0x00;
498 }
499 // transmit first byte from buffer, fall
500 case TW_ST_DATA_ACK: // byte sent, ack returned
501 // copy data to output register
502 TWDR = twi_txBuffer[twi_txBufferIndex++];
503 // if there is more to send, ack, otherwise nack
504 if(twi_txBufferIndex < twi_txBufferLength){
505 twi_reply(1);
506 }else{
507 twi_reply(0);
508 }
509 break;
510 case TW_ST_DATA_NACK: // received nack, we are done
511 case TW_ST_LAST_DATA: // received ack, but we are done already!
512 // ack future responses
513 twi_reply(1);
514 // leave slave receiver state
515 twi_state = TWI_READY;
516 break;
517
518 // All
519 case TW_NO_INFO: // no state information
520 break;
521 case TW_BUS_ERROR: // bus error, illegal stop/start
522 twi_error = TW_BUS_ERROR;
523 twi_stop();
524 break;
525 }
526 }
527
@@ -0,0 +1,53
1 /*
2 twi.h - TWI/I2C library for Wiring & Arduino
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef twi_h
21 #define twi_h
22
23 #include <inttypes.h>
24
25 //#define ATMEGA8
26
27 #ifndef TWI_FREQ
28 #define TWI_FREQ 100000L
29 #endif
30
31 #ifndef TWI_BUFFER_LENGTH
32 #define TWI_BUFFER_LENGTH 32
33 #endif
34
35 #define TWI_READY 0
36 #define TWI_MRX 1
37 #define TWI_MTX 2
38 #define TWI_SRX 3
39 #define TWI_STX 4
40
41 void twi_init(void);
42 void twi_setAddress(uint8_t);
43 uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
44 uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
45 uint8_t twi_transmit(const uint8_t*, uint8_t);
46 void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
47 void twi_attachSlaveTxEvent( void (*)(void) );
48 void twi_reply(uint8_t);
49 void twi_stop(void);
50 void twi_releaseBus(void);
51
52 #endif
53
@@ -0,0 +1,324
1 /*
2 wiring.c - Partial implementation of the Wiring API for the ATmega8.
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2005-2006 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 $Id$
23 */
24
25 #include "wiring_private.h"
26
27 // the prescaler is set so that timer0 ticks every 64 clock cycles, and the
28 // the overflow handler is called every 256 ticks.
29 #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
30
31 // the whole number of milliseconds per timer0 overflow
32 #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
33
34 // the fractional number of milliseconds per timer0 overflow. we shift right
35 // by three to fit these numbers into a byte. (for the clock speeds we care
36 // about - 8 and 16 MHz - this doesn't lose precision.)
37 #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
38 #define FRACT_MAX (1000 >> 3)
39
40 volatile unsigned long timer0_overflow_count = 0;
41 volatile unsigned long timer0_millis = 0;
42 static unsigned char timer0_fract = 0;
43
44 #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
45 ISR(TIM0_OVF_vect)
46 #else
47 ISR(TIMER0_OVF_vect)
48 #endif
49 {
50 // copy these to local variables so they can be stored in registers
51 // (volatile variables must be read from memory on every access)
52 unsigned long m = timer0_millis;
53 unsigned char f = timer0_fract;
54
55 m += MILLIS_INC;
56 f += FRACT_INC;
57 if (f >= FRACT_MAX) {
58 f -= FRACT_MAX;
59 m += 1;
60 }
61
62 timer0_fract = f;
63 timer0_millis = m;
64 timer0_overflow_count++;
65 }
66
67 unsigned long millis()
68 {
69 unsigned long m;
70 uint8_t oldSREG = SREG;
71
72 // disable interrupts while we read timer0_millis or we might get an
73 // inconsistent value (e.g. in the middle of a write to timer0_millis)
74 cli();
75 m = timer0_millis;
76 SREG = oldSREG;
77
78 return m;
79 }
80
81 unsigned long micros() {
82 unsigned long m;
83 uint8_t oldSREG = SREG, t;
84
85 cli();
86 m = timer0_overflow_count;
87 #if defined(TCNT0)
88 t = TCNT0;
89 #elif defined(TCNT0L)
90 t = TCNT0L;
91 #else
92 #error TIMER 0 not defined
93 #endif
94
95
96 #ifdef TIFR0
97 if ((TIFR0 & _BV(TOV0)) && (t < 255))
98 m++;
99 #else
100 if ((TIFR & _BV(TOV0)) && (t < 255))
101 m++;
102 #endif
103
104 SREG = oldSREG;
105
106 return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
107 }
108
109 void delay(unsigned long ms)
110 {
111 uint16_t start = (uint16_t)micros();
112
113 while (ms > 0) {
114 if (((uint16_t)micros() - start) >= 1000) {
115 ms--;
116 start += 1000;
117 }
118 }
119 }
120
121 /* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */
122 void delayMicroseconds(unsigned int us)
123 {
124 // calling avrlib's delay_us() function with low values (e.g. 1 or
125 // 2 microseconds) gives delays longer than desired.
126 //delay_us(us);
127 #if F_CPU >= 20000000L
128 // for the 20 MHz clock on rare Arduino boards
129
130 // for a one-microsecond delay, simply wait 2 cycle and return. The overhead
131 // of the function call yields a delay of exactly a one microsecond.
132 __asm__ __volatile__ (
133 "nop" "\n\t"
134 "nop"); //just waiting 2 cycle
135 if (--us == 0)
136 return;
137
138 // the following loop takes a 1/5 of a microsecond (4 cycles)
139 // per iteration, so execute it five times for each microsecond of
140 // delay requested.
141 us = (us<<2) + us; // x5 us
142
143 // account for the time taken in the preceeding commands.
144 us -= 2;
145
146 #elif F_CPU >= 16000000L
147 // for the 16 MHz clock on most Arduino boards
148
149 // for a one-microsecond delay, simply return. the overhead
150 // of the function call yields a delay of approximately 1 1/8 us.
151 if (--us == 0)
152 return;
153
154 // the following loop takes a quarter of a microsecond (4 cycles)
155 // per iteration, so execute it four times for each microsecond of
156 // delay requested.
157 us <<= 2;
158
159 // account for the time taken in the preceeding commands.
160 us -= 2;
161 #else
162 // for the 8 MHz internal clock on the ATmega168
163
164 // for a one- or two-microsecond delay, simply return. the overhead of
165 // the function calls takes more than two microseconds. can't just
166 // subtract two, since us is unsigned; we'd overflow.
167 if (--us == 0)
168 return;
169 if (--us == 0)
170 return;
171
172 // the following loop takes half of a microsecond (4 cycles)
173 // per iteration, so execute it twice for each microsecond of
174 // delay requested.
175 us <<= 1;
176
177 // partially compensate for the time taken by the preceeding commands.
178 // we can't subtract any more than this or we'd overflow w/ small delays.
179 us--;
180 #endif
181
182 // busy wait
183 __asm__ __volatile__ (
184 "1: sbiw %0,1" "\n\t" // 2 cycles
185 "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
186 );
187 }
188
189 void init()
190 {
191 // this needs to be called before setup() or some functions won't
192 // work there
193 sei();
194
195 // on the ATmega168, timer 0 is also used for fast hardware pwm
196 // (using phase-correct PWM would mean that timer 0 overflowed half as often
197 // resulting in different millis() behavior on the ATmega8 and ATmega168)
198 #if defined(TCCR0A) && defined(WGM01)
199 sbi(TCCR0A, WGM01);
200 sbi(TCCR0A, WGM00);
201 #endif
202
203 // set timer 0 prescale factor to 64
204 #if defined(__AVR_ATmega128__)
205 // CPU specific: different values for the ATmega128
206 sbi(TCCR0, CS02);
207 #elif defined(TCCR0) && defined(CS01) && defined(CS00)
208 // this combination is for the standard atmega8
209 sbi(TCCR0, CS01);
210 sbi(TCCR0, CS00);
211 #elif defined(TCCR0B) && defined(CS01) && defined(CS00)
212 // this combination is for the standard 168/328/1280/2560
213 sbi(TCCR0B, CS01);
214 sbi(TCCR0B, CS00);
215 #elif defined(TCCR0A) && defined(CS01) && defined(CS00)
216 // this combination is for the __AVR_ATmega645__ series
217 sbi(TCCR0A, CS01);
218 sbi(TCCR0A, CS00);
219 #else
220 #error Timer 0 prescale factor 64 not set correctly
221 #endif
222
223 // enable timer 0 overflow interrupt
224 #if defined(TIMSK) && defined(TOIE0)
225 sbi(TIMSK, TOIE0);
226 #elif defined(TIMSK0) && defined(TOIE0)
227 sbi(TIMSK0, TOIE0);
228 #else
229 #error Timer 0 overflow interrupt not set correctly
230 #endif
231
232 // timers 1 and 2 are used for phase-correct hardware pwm
233 // this is better for motors as it ensures an even waveform
234 // note, however, that fast pwm mode can achieve a frequency of up
235 // 8 MHz (with a 16 MHz clock) at 50% duty cycle
236
237 #if defined(TCCR1B) && defined(CS11) && defined(CS10)
238 TCCR1B = 0;
239
240 // set timer 1 prescale factor to 64
241 sbi(TCCR1B, CS11);
242 #if F_CPU >= 8000000L
243 sbi(TCCR1B, CS10);
244 #endif
245 #elif defined(TCCR1) && defined(CS11) && defined(CS10)
246 sbi(TCCR1, CS11);
247 #if F_CPU >= 8000000L
248 sbi(TCCR1, CS10);
249 #endif
250 #endif
251 // put timer 1 in 8-bit phase correct pwm mode
252 #if defined(TCCR1A) && defined(WGM10)
253 sbi(TCCR1A, WGM10);
254 #elif defined(TCCR1)
255 #warning this needs to be finished
256 #endif
257
258 // set timer 2 prescale factor to 64
259 #if defined(TCCR2) && defined(CS22)
260 sbi(TCCR2, CS22);
261 #elif defined(TCCR2B) && defined(CS22)
262 sbi(TCCR2B, CS22);
263 #else
264 #warning Timer 2 not finished (may not be present on this CPU)
265 #endif
266
267 // configure timer 2 for phase correct pwm (8-bit)
268 #if defined(TCCR2) && defined(WGM20)
269 sbi(TCCR2, WGM20);
270 #elif defined(TCCR2A) && defined(WGM20)
271 sbi(TCCR2A, WGM20);
272 #else
273 #warning Timer 2 not finished (may not be present on this CPU)
274 #endif
275
276 #if defined(TCCR3B) && defined(CS31) && defined(WGM30)
277 sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64
278 sbi(TCCR3B, CS30);
279 sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
280 #endif
281
282 #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
283 sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
284 sbi(TCCR4B, CS41);
285 sbi(TCCR4B, CS40);
286 sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
287 sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
288 sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
289 #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
290 #if defined(TCCR4B) && defined(CS41) && defined(WGM40)
291 sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
292 sbi(TCCR4B, CS40);
293 sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
294 #endif
295 #endif /* end timer4 block for ATMEGA1280/2560 and similar */
296
297 #if defined(TCCR5B) && defined(CS51) && defined(WGM50)
298 sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
299 sbi(TCCR5B, CS50);
300 sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode
301 #endif
302
303 #if defined(ADCSRA)
304 // set a2d prescale factor to 128
305 // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
306 // XXX: this will not work properly for other clock speeds, and
307 // this code should use F_CPU to determine the prescale factor.
308 sbi(ADCSRA, ADPS2);
309 sbi(ADCSRA, ADPS1);
310 sbi(ADCSRA, ADPS0);
311
312 // enable a2d conversions
313 sbi(ADCSRA, ADEN);
314 #endif
315
316 // the bootloader connects pins 0 and 1 to the USART; disconnect them
317 // here so they can be used as normal digital i/o; they will be
318 // reconnected in Serial.begin()
319 #if defined(UCSRB)
320 UCSRB = 0;
321 #elif defined(UCSR0B)
322 UCSR0B = 0;
323 #endif
324 }
@@ -0,0 +1,284
1 /*
2 wiring_analog.c - analog input and output
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2005-2006 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 Modified 28 September 2010 by Mark Sproul
23
24 $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
25 */
26
27 #include "wiring_private.h"
28 #include "pins_arduino.h"
29
30 uint8_t analog_reference = DEFAULT;
31
32 void analogReference(uint8_t mode)
33 {
34 // can't actually set the register here because the default setting
35 // will connect AVCC and the AREF pin, which would cause a short if
36 // there's something connected to AREF.
37 analog_reference = mode;
38 }
39
40 int analogRead(uint8_t pin)
41 {
42 uint8_t low, high;
43
44 #if defined(analogPinToChannel)
45 #if defined(__AVR_ATmega32U4__)
46 if (pin >= 18) pin -= 18; // allow for channel or pin numbers
47 #endif
48 pin = analogPinToChannel(pin);
49 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
50 if (pin >= 54) pin -= 54; // allow for channel or pin numbers
51 #elif defined(__AVR_ATmega32U4__)
52 if (pin >= 18) pin -= 18; // allow for channel or pin numbers
53 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
54 if (pin >= 24) pin -= 24; // allow for channel or pin numbers
55 #else
56 if (pin >= 14) pin -= 14; // allow for channel or pin numbers
57 #endif
58
59 #if defined(ADCSRB) && defined(MUX5)
60 // the MUX5 bit of ADCSRB selects whether we're reading from channels
61 // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
62 ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
63 #endif
64
65 // set the analog reference (high two bits of ADMUX) and select the
66 // channel (low 4 bits). this also sets ADLAR (left-adjust result)
67 // to 0 (the default).
68 #if defined(ADMUX)
69 ADMUX = (analog_reference << 6) | (pin & 0x07);
70 #endif
71
72 // without a delay, we seem to read from the wrong channel
73 //delay(1);
74
75 #if defined(ADCSRA) && defined(ADCL)
76 // start the conversion
77 sbi(ADCSRA, ADSC);
78
79 // ADSC is cleared when the conversion finishes
80 while (bit_is_set(ADCSRA, ADSC));
81
82 // we have to read ADCL first; doing so locks both ADCL
83 // and ADCH until ADCH is read. reading ADCL second would
84 // cause the results of each conversion to be discarded,
85 // as ADCL and ADCH would be locked when it completed.
86 low = ADCL;
87 high = ADCH;
88 #else
89 // we dont have an ADC, return 0
90 low = 0;
91 high = 0;
92 #endif
93
94 // combine the two bytes
95 return (high << 8) | low;
96 }
97
98 // Right now, PWM output only works on the pins with
99 // hardware support. These are defined in the appropriate
100 // pins_*.c file. For the rest of the pins, we default
101 // to digital output.
102 void analogWrite(uint8_t pin, int val)
103 {
104 // We need to make sure the PWM output is enabled for those pins
105 // that support it, as we turn it off when digitally reading or
106 // writing with them. Also, make sure the pin is in output mode
107 // for consistenty with Wiring, which doesn't require a pinMode
108 // call for the analog output pins.
109 pinMode(pin, OUTPUT);
110 if (val == 0)
111 {
112 digitalWrite(pin, LOW);
113 }
114 else if (val == 255)
115 {
116 digitalWrite(pin, HIGH);
117 }
118 else
119 {
120 switch(digitalPinToTimer(pin))
121 {
122 // XXX fix needed for atmega8
123 #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
124 case TIMER0A:
125 // connect pwm to pin on timer 0
126 sbi(TCCR0, COM00);
127 OCR0 = val; // set pwm duty
128 break;
129 #endif
130
131 #if defined(TCCR0A) && defined(COM0A1)
132 case TIMER0A:
133 // connect pwm to pin on timer 0, channel A
134 sbi(TCCR0A, COM0A1);
135 OCR0A = val; // set pwm duty
136 break;
137 #endif
138
139 #if defined(TCCR0A) && defined(COM0B1)
140 case TIMER0B:
141 // connect pwm to pin on timer 0, channel B
142 sbi(TCCR0A, COM0B1);
143 OCR0B = val; // set pwm duty
144 break;
145 #endif
146
147 #if defined(TCCR1A) && defined(COM1A1)
148 case TIMER1A:
149 // connect pwm to pin on timer 1, channel A
150 sbi(TCCR1A, COM1A1);
151 OCR1A = val; // set pwm duty
152 break;
153 #endif
154
155 #if defined(TCCR1A) && defined(COM1B1)
156 case TIMER1B:
157 // connect pwm to pin on timer 1, channel B
158 sbi(TCCR1A, COM1B1);
159 OCR1B = val; // set pwm duty
160 break;
161 #endif
162
163 #if defined(TCCR2) && defined(COM21)
164 case TIMER2:
165 // connect pwm to pin on timer 2
166 sbi(TCCR2, COM21);
167 OCR2 = val; // set pwm duty
168 break;
169 #endif
170
171 #if defined(TCCR2A) && defined(COM2A1)
172 case TIMER2A:
173 // connect pwm to pin on timer 2, channel A
174 sbi(TCCR2A, COM2A1);
175 OCR2A = val; // set pwm duty
176 break;
177 #endif
178
179 #if defined(TCCR2A) && defined(COM2B1)
180 case TIMER2B:
181 // connect pwm to pin on timer 2, channel B
182 sbi(TCCR2A, COM2B1);
183 OCR2B = val; // set pwm duty
184 break;
185 #endif
186
187 #if defined(TCCR3A) && defined(COM3A1)
188 case TIMER3A:
189 // connect pwm to pin on timer 3, channel A
190 sbi(TCCR3A, COM3A1);
191 OCR3A = val; // set pwm duty
192 break;
193 #endif
194
195 #if defined(TCCR3A) && defined(COM3B1)
196 case TIMER3B:
197 // connect pwm to pin on timer 3, channel B
198 sbi(TCCR3A, COM3B1);
199 OCR3B = val; // set pwm duty
200 break;
201 #endif
202
203 #if defined(TCCR3A) && defined(COM3C1)
204 case TIMER3C:
205 // connect pwm to pin on timer 3, channel C
206 sbi(TCCR3A, COM3C1);
207 OCR3C = val; // set pwm duty
208 break;
209 #endif
210
211 #if defined(TCCR4A)
212 case TIMER4A:
213 //connect pwm to pin on timer 4, channel A
214 sbi(TCCR4A, COM4A1);
215 #if defined(COM4A0) // only used on 32U4
216 cbi(TCCR4A, COM4A0);
217 #endif
218 OCR4A = val; // set pwm duty
219 break;
220 #endif
221
222 #if defined(TCCR4A) && defined(COM4B1)
223 case TIMER4B:
224 // connect pwm to pin on timer 4, channel B
225 sbi(TCCR4A, COM4B1);
226 OCR4B = val; // set pwm duty
227 break;
228 #endif
229
230 #if defined(TCCR4A) && defined(COM4C1)
231 case TIMER4C:
232 // connect pwm to pin on timer 4, channel C
233 sbi(TCCR4A, COM4C1);
234 OCR4C = val; // set pwm duty
235 break;
236 #endif
237
238 #if defined(TCCR4C) && defined(COM4D1)
239 case TIMER4D:
240 // connect pwm to pin on timer 4, channel D
241 sbi(TCCR4C, COM4D1);
242 #if defined(COM4D0) // only used on 32U4
243 cbi(TCCR4C, COM4D0);
244 #endif
245 OCR4D = val; // set pwm duty
246 break;
247 #endif
248
249
250 #if defined(TCCR5A) && defined(COM5A1)
251 case TIMER5A:
252 // connect pwm to pin on timer 5, channel A
253 sbi(TCCR5A, COM5A1);
254 OCR5A = val; // set pwm duty
255 break;
256 #endif
257
258 #if defined(TCCR5A) && defined(COM5B1)
259 case TIMER5B:
260 // connect pwm to pin on timer 5, channel B
261 sbi(TCCR5A, COM5B1);
262 OCR5B = val; // set pwm duty
263 break;
264 #endif
265
266 #if defined(TCCR5A) && defined(COM5C1)
267 case TIMER5C:
268 // connect pwm to pin on timer 5, channel C
269 sbi(TCCR5A, COM5C1);
270 OCR5C = val; // set pwm duty
271 break;
272 #endif
273
274 case NOT_ON_TIMER:
275 default:
276 if (val < 128) {
277 digitalWrite(pin, LOW);
278 } else {
279 digitalWrite(pin, HIGH);
280 }
281 }
282 }
283 }
284
@@ -0,0 +1,178
1 /*
2 wiring_digital.c - digital input and output functions
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2005-2006 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 Modified 28 September 2010 by Mark Sproul
23
24 $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
25 */
26
27 #define ARDUINO_MAIN
28 #include "wiring_private.h"
29 #include "pins_arduino.h"
30
31 void pinMode(uint8_t pin, uint8_t mode)
32 {
33 uint8_t bit = digitalPinToBitMask(pin);
34 uint8_t port = digitalPinToPort(pin);
35 volatile uint8_t *reg, *out;
36
37 if (port == NOT_A_PIN) return;
38
39 // JWS: can I let the optimizer do this?
40 reg = portModeRegister(port);
41 out = portOutputRegister(port);
42
43 if (mode == INPUT) {
44 uint8_t oldSREG = SREG;
45 cli();
46 *reg &= ~bit;
47 *out &= ~bit;
48 SREG = oldSREG;
49 } else if (mode == INPUT_PULLUP) {
50 uint8_t oldSREG = SREG;
51 cli();
52 *reg &= ~bit;
53 *out |= bit;
54 SREG = oldSREG;
55 } else {
56 uint8_t oldSREG = SREG;
57 cli();
58 *reg |= bit;
59 SREG = oldSREG;
60 }
61 }
62
63 // Forcing this inline keeps the callers from having to push their own stuff
64 // on the stack. It is a good performance win and only takes 1 more byte per
65 // user than calling. (It will take more bytes on the 168.)
66 //
67 // But shouldn't this be moved into pinMode? Seems silly to check and do on
68 // each digitalread or write.
69 //
70 // Mark Sproul:
71 // - Removed inline. Save 170 bytes on atmega1280
72 // - changed to a switch statment; added 32 bytes but much easier to read and maintain.
73 // - Added more #ifdefs, now compiles for atmega645
74 //
75 //static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline));
76 //static inline void turnOffPWM(uint8_t timer)
77 static void turnOffPWM(uint8_t timer)
78 {
79 switch (timer)
80 {
81 #if defined(TCCR1A) && defined(COM1A1)
82 case TIMER1A: cbi(TCCR1A, COM1A1); break;
83 #endif
84 #if defined(TCCR1A) && defined(COM1B1)
85 case TIMER1B: cbi(TCCR1A, COM1B1); break;
86 #endif
87
88 #if defined(TCCR2) && defined(COM21)
89 case TIMER2: cbi(TCCR2, COM21); break;
90 #endif
91
92 #if defined(TCCR0A) && defined(COM0A1)
93 case TIMER0A: cbi(TCCR0A, COM0A1); break;
94 #endif
95
96 #if defined(TIMER0B) && defined(COM0B1)
97 case TIMER0B: cbi(TCCR0A, COM0B1); break;
98 #endif
99 #if defined(TCCR2A) && defined(COM2A1)
100 case TIMER2A: cbi(TCCR2A, COM2A1); break;
101 #endif
102 #if defined(TCCR2A) && defined(COM2B1)
103 case TIMER2B: cbi(TCCR2A, COM2B1); break;
104 #endif
105
106 #if defined(TCCR3A) && defined(COM3A1)
107 case TIMER3A: cbi(TCCR3A, COM3A1); break;
108 #endif
109 #if defined(TCCR3A) && defined(COM3B1)
110 case TIMER3B: cbi(TCCR3A, COM3B1); break;
111 #endif
112 #if defined(TCCR3A) && defined(COM3C1)
113 case TIMER3C: cbi(TCCR3A, COM3C1); break;
114 #endif
115
116 #if defined(TCCR4A) && defined(COM4A1)
117 case TIMER4A: cbi(TCCR4A, COM4A1); break;
118 #endif
119 #if defined(TCCR4A) && defined(COM4B1)
120 case TIMER4B: cbi(TCCR4A, COM4B1); break;
121 #endif
122 #if defined(TCCR4A) && defined(COM4C1)
123 case TIMER4C: cbi(TCCR4A, COM4C1); break;
124 #endif
125 #if defined(TCCR4C) && defined(COM4D1)
126 case TIMER4D: cbi(TCCR4C, COM4D1); break;
127 #endif
128
129 #if defined(TCCR5A)
130 case TIMER5A: cbi(TCCR5A, COM5A1); break;
131 case TIMER5B: cbi(TCCR5A, COM5B1); break;
132 case TIMER5C: cbi(TCCR5A, COM5C1); break;
133 #endif
134 }
135 }
136
137 void digitalWrite(uint8_t pin, uint8_t val)
138 {
139 uint8_t timer = digitalPinToTimer(pin);
140 uint8_t bit = digitalPinToBitMask(pin);
141 uint8_t port = digitalPinToPort(pin);
142 volatile uint8_t *out;
143
144 if (port == NOT_A_PIN) return;
145
146 // If the pin that support PWM output, we need to turn it off
147 // before doing a digital write.
148 if (timer != NOT_ON_TIMER) turnOffPWM(timer);
149
150 out = portOutputRegister(port);
151
152 uint8_t oldSREG = SREG;
153 cli();
154
155 if (val == LOW) {
156 *out &= ~bit;
157 } else {
158 *out |= bit;
159 }
160
161 SREG = oldSREG;
162 }
163
164 int digitalRead(uint8_t pin)
165 {
166 uint8_t timer = digitalPinToTimer(pin);
167 uint8_t bit = digitalPinToBitMask(pin);
168 uint8_t port = digitalPinToPort(pin);
169
170 if (port == NOT_A_PIN) return LOW;
171
172 // If the pin that support PWM output, we need to turn it off
173 // before getting a digital reading.
174 if (timer != NOT_ON_TIMER) turnOffPWM(timer);
175
176 if (*portInputRegister(port) & bit) return HIGH;
177 return LOW;
178 }
@@ -0,0 +1,71
1 /*
2 wiring_private.h - Internal header file.
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2005-2006 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $
23 */
24
25 #ifndef WiringPrivate_h
26 #define WiringPrivate_h
27
28 #include <avr/io.h>
29 #include <avr/interrupt.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32
33 #include "Arduino.h"
34
35 #ifdef __cplusplus
36 extern "C"{
37 #endif
38
39 #ifndef cbi
40 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
41 #endif
42 #ifndef sbi
43 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
44 #endif
45
46 #define EXTERNAL_INT_0 0
47 #define EXTERNAL_INT_1 1
48 #define EXTERNAL_INT_2 2
49 #define EXTERNAL_INT_3 3
50 #define EXTERNAL_INT_4 4
51 #define EXTERNAL_INT_5 5
52 #define EXTERNAL_INT_6 6
53 #define EXTERNAL_INT_7 7
54
55 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
56 #define EXTERNAL_NUM_INTERRUPTS 8
57 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
58 #define EXTERNAL_NUM_INTERRUPTS 3
59 #elif defined(__AVR_ATmega32U4__)
60 #define EXTERNAL_NUM_INTERRUPTS 5
61 #else
62 #define EXTERNAL_NUM_INTERRUPTS 2
63 #endif
64
65 typedef void (*voidFuncPtr)(void);
66
67 #ifdef __cplusplus
68 } // extern "C"
69 #endif
70
71 #endif
@@ -0,0 +1,69
1 /*
2 wiring_pulse.c - pulseIn() function
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2005-2006 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
23 */
24
25 #include "wiring_private.h"
26 #include "pins_arduino.h"
27
28 /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
29 * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
30 * to 3 minutes in length, but must be called at least a few dozen microseconds
31 * before the start of the pulse. */
32 unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
33 {
34 // cache the port and bit of the pin in order to speed up the
35 // pulse width measuring loop and achieve finer resolution. calling
36 // digitalRead() instead yields much coarser resolution.
37 uint8_t bit = digitalPinToBitMask(pin);
38 uint8_t port = digitalPinToPort(pin);
39 uint8_t stateMask = (state ? bit : 0);
40 unsigned long width = 0; // keep initialization out of time critical area
41
42 // convert the timeout from microseconds to a number of times through
43 // the initial loop; it takes 16 clock cycles per iteration.
44 unsigned long numloops = 0;
45 unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
46
47 // wait for any previous pulse to end
48 while ((*portInputRegister(port) & bit) == stateMask)
49 if (numloops++ == maxloops)
50 return 0;
51
52 // wait for the pulse to start
53 while ((*portInputRegister(port) & bit) != stateMask)
54 if (numloops++ == maxloops)
55 return 0;
56
57 // wait for the pulse to stop
58 while ((*portInputRegister(port) & bit) == stateMask) {
59 if (numloops++ == maxloops)
60 return 0;
61 width++;
62 }
63
64 // convert the reading to microseconds. The loop has been determined
65 // to be 20 clock cycles long and have about 16 clocks between the edge
66 // and the start of the loop. There will be some error introduced by
67 // the interrupt handlers.
68 return clockCyclesToMicroseconds(width * 21 + 16);
69 }
@@ -0,0 +1,55
1 /*
2 wiring_shift.c - shiftOut() function
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2005-2006 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
23 */
24
25 #include "wiring_private.h"
26
27 uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
28 uint8_t value = 0;
29 uint8_t i;
30
31 for (i = 0; i < 8; ++i) {
32 digitalWrite(clockPin, HIGH);
33 if (bitOrder == LSBFIRST)
34 value |= digitalRead(dataPin) << i;
35 else
36 value |= digitalRead(dataPin) << (7 - i);
37 digitalWrite(clockPin, LOW);
38 }
39 return value;
40 }
41
42 void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
43 {
44 uint8_t i;
45
46 for (i = 0; i < 8; i++) {
47 if (bitOrder == LSBFIRST)
48 digitalWrite(dataPin, !!(val & (1 << i)));
49 else
50 digitalWrite(dataPin, !!(val & (1 << (7 - i))));
51
52 digitalWrite(clockPin, HIGH);
53 digitalWrite(clockPin, LOW);
54 }
55 }
@@ -0,0 +1,50
1 /*
2 EEPROM.cpp - EEPROM library
3 Copyright (c) 2006 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /******************************************************************************
21 * Includes
22 ******************************************************************************/
23
24 #include <avr/eeprom.h>
25 #include "Arduino.h"
26 #include "EEPROM.h"
27
28 /******************************************************************************
29 * Definitions
30 ******************************************************************************/
31
32 /******************************************************************************
33 * Constructors
34 ******************************************************************************/
35
36 /******************************************************************************
37 * User API
38 ******************************************************************************/
39
40 uint8_t EEPROMClass::read(int address)
41 {
42 return eeprom_read_byte((unsigned char *) address);
43 }
44
45 void EEPROMClass::write(int address, uint8_t value)
46 {
47 eeprom_write_byte((unsigned char *) address, value);
48 }
49
50 EEPROMClass EEPROM;
@@ -0,0 +1,35
1 /*
2 EEPROM.h - EEPROM library
3 Copyright (c) 2006 David A. Mellis. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef EEPROM_h
21 #define EEPROM_h
22
23 #include <inttypes.h>
24
25 class EEPROMClass
26 {
27 public:
28 uint8_t read(int);
29 void write(int, uint8_t);
30 };
31
32 extern EEPROMClass EEPROM;
33
34 #endif
35
@@ -0,0 +1,23
1 /*
2 * EEPROM Clear
3 *
4 * Sets all of the bytes of the EEPROM to 0.
5 * This example code is in the public domain.
6
7 */
8
9 #include <EEPROM.h>
10
11 void setup()
12 {
13 // write a 0 to all 512 bytes of the EEPROM
14 for (int i = 0; i < 512; i++)
15 EEPROM.write(i, 0);
16
17 // turn the LED on when we're done
18 digitalWrite(13, HIGH);
19 }
20
21 void loop()
22 {
23 }
@@ -0,0 +1,43
1 /*
2 * EEPROM Read
3 *
4 * Reads the value of each byte of the EEPROM and prints it
5 * to the computer.
6 * This example code is in the public domain.
7 */
8
9 #include <EEPROM.h>
10
11 // start reading from the first byte (address 0) of the EEPROM
12 int address = 0;
13 byte value;
14
15 void setup()
16 {
17 // initialize serial and wait for port to open:
18 Serial.begin(9600);
19 while (!Serial) {
20 ; // wait for serial port to connect. Needed for Leonardo only
21 }
22 }
23
24 void loop()
25 {
26 // read a byte from the current address of the EEPROM
27 value = EEPROM.read(address);
28
29 Serial.print(address);
30 Serial.print("\t");
31 Serial.print(value, DEC);
32 Serial.println();
33
34 // advance to the next address of the EEPROM
35 address = address + 1;
36
37 // there are only 512 bytes of EEPROM, from 0 to 511, so if we're
38 // on address 512, wrap around to address 0
39 if (address == 512)
40 address = 0;
41
42 delay(500);
43 }
@@ -0,0 +1,38
1 /*
2 * EEPROM Write
3 *
4 * Stores values read from analog input 0 into the EEPROM.
5 * These values will stay in the EEPROM when the board is
6 * turned off and may be retrieved later by another sketch.
7 */
8
9 #include <EEPROM.h>
10
11 // the current address in the EEPROM (i.e. which byte
12 // we're going to write to next)
13 int addr = 0;
14
15 void setup()
16 {
17 }
18
19 void loop()
20 {
21 // need to divide by 4 because analog inputs range from
22 // 0 to 1023 and each byte of the EEPROM can only hold a
23 // value from 0 to 255.
24 int val = analogRead(0) / 4;
25
26 // write the value to the appropriate byte of the EEPROM.
27 // these values will remain there when the board is
28 // turned off.
29 EEPROM.write(addr, val);
30
31 // advance to the next address. there are 512 bytes in
32 // the EEPROM, so go back to 0 when we hit 512.
33 addr = addr + 1;
34 if (addr == 512)
35 addr = 0;
36
37 delay(100);
38 }
@@ -0,0 +1,18
1 #######################################
2 # Syntax Coloring Map For Ultrasound
3 #######################################
4
5 #######################################
6 # Datatypes (KEYWORD1)
7 #######################################
8
9 EEPROM KEYWORD1
10
11 #######################################
12 # Methods and Functions (KEYWORD2)
13 #######################################
14
15 #######################################
16 # Constants (LITERAL1)
17 #######################################
18
@@ -0,0 +1,66
1 /*
2 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
3 * SPI Master library for arduino.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of either the GNU General Public License version 2
7 * or the GNU Lesser General Public License version 2.1, both as
8 * published by the Free Software Foundation.
9 */
10
11 #include "pins_arduino.h"
12 #include "SPI.h"
13
14 SPIClass SPI;
15
16 void SPIClass::begin() {
17
18 // Set SS to high so a connected chip will be "deselected" by default
19 digitalWrite(SS, HIGH);
20
21 // When the SS pin is set as OUTPUT, it can be used as
22 // a general purpose output port (it doesn't influence
23 // SPI operations).
24 pinMode(SS, OUTPUT);
25
26 // Warning: if the SS pin ever becomes a LOW INPUT then SPI
27 // automatically switches to Slave, so the data direction of
28 // the SS pin MUST be kept as OUTPUT.
29 SPCR |= _BV(MSTR);
30 SPCR |= _BV(SPE);
31
32 // Set direction register for SCK and MOSI pin.
33 // MISO pin automatically overrides to INPUT.
34 // By doing this AFTER enabling SPI, we avoid accidentally
35 // clocking in a single bit since the lines go directly
36 // from "input" to SPI control.
37 // http://code.google.com/p/arduino/issues/detail?id=888
38 pinMode(SCK, OUTPUT);
39 pinMode(MOSI, OUTPUT);
40 }
41
42
43 void SPIClass::end() {
44 SPCR &= ~_BV(SPE);
45 }
46
47 void SPIClass::setBitOrder(uint8_t bitOrder)
48 {
49 if(bitOrder == LSBFIRST) {
50 SPCR |= _BV(DORD);
51 } else {
52 SPCR &= ~(_BV(DORD));
53 }
54 }
55
56 void SPIClass::setDataMode(uint8_t mode)
57 {
58 SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
59 }
60
61 void SPIClass::setClockDivider(uint8_t rate)
62 {
63 SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
64 SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
65 }
66
@@ -0,0 +1,70
1 /*
2 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
3 * SPI Master library for arduino.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of either the GNU General Public License version 2
7 * or the GNU Lesser General Public License version 2.1, both as
8 * published by the Free Software Foundation.
9 */
10
11 #ifndef _SPI_H_INCLUDED
12 #define _SPI_H_INCLUDED
13
14 #include <stdio.h>
15 #include <Arduino.h>
16 #include <avr/pgmspace.h>
17
18 #define SPI_CLOCK_DIV4 0x00
19 #define SPI_CLOCK_DIV16 0x01
20 #define SPI_CLOCK_DIV64 0x02
21 #define SPI_CLOCK_DIV128 0x03
22 #define SPI_CLOCK_DIV2 0x04
23 #define SPI_CLOCK_DIV8 0x05
24 #define SPI_CLOCK_DIV32 0x06
25 //#define SPI_CLOCK_DIV64 0x07
26
27 #define SPI_MODE0 0x00
28 #define SPI_MODE1 0x04
29 #define SPI_MODE2 0x08
30 #define SPI_MODE3 0x0C
31
32 #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
33 #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
34 #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
35
36 class SPIClass {
37 public:
38 inline static byte transfer(byte _data);
39
40 // SPI Configuration methods
41
42 inline static void attachInterrupt();
43 inline static void detachInterrupt(); // Default
44
45 static void begin(); // Default
46 static void end();
47
48 static void setBitOrder(uint8_t);
49 static void setDataMode(uint8_t);
50 static void setClockDivider(uint8_t);
51 };
52
53 extern SPIClass SPI;
54
55 byte SPIClass::transfer(byte _data) {
56 SPDR = _data;
57 while (!(SPSR & _BV(SPIF)))
58 ;
59 return SPDR;
60 }
61
62 void SPIClass::attachInterrupt() {
63 SPCR |= _BV(SPIE);
64 }
65
66 void SPIClass::detachInterrupt() {
67 SPCR &= ~_BV(SPIE);
68 }
69
70 #endif
@@ -0,0 +1,143
1 /*
2 SCP1000 Barometric Pressure Sensor Display
3
4 Shows the output of a Barometric Pressure Sensor on a
5 Uses the SPI library. For details on the sensor, see:
6 http://www.sparkfun.com/commerce/product_info.php?products_id=8161
7 http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
8
9 This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
10 http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
11
12 Circuit:
13 SCP1000 sensor attached to pins 6, 7, 10 - 13:
14 DRDY: pin 6
15 CSB: pin 7
16 MOSI: pin 11
17 MISO: pin 12
18 SCK: pin 13
19
20 created 31 July 2010
21 modified 14 August 2010
22 by Tom Igoe
23 */
24
25 // the sensor communicates using SPI, so include the library:
26 #include <SPI.h>
27
28 //Sensor's memory register addresses:
29 const int PRESSURE = 0x1F; //3 most significant bits of pressure
30 const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure
31 const int TEMPERATURE = 0x21; //16 bit temperature reading
32 const byte READ = 0b11111100; // SCP1000's read command
33 const byte WRITE = 0b00000010; // SCP1000's write command
34
35 // pins used for the connection with the sensor
36 // the other you need are controlled by the SPI library):
37 const int dataReadyPin = 6;
38 const int chipSelectPin = 7;
39
40 void setup() {
41 Serial.begin(9600);
42
43 // start the SPI library:
44 SPI.begin();
45
46 // initalize the data ready and chip select pins:
47 pinMode(dataReadyPin, INPUT);
48 pinMode(chipSelectPin, OUTPUT);
49
50 //Configure SCP1000 for low noise configuration:
51 writeRegister(0x02, 0x2D);
52 writeRegister(0x01, 0x03);
53 writeRegister(0x03, 0x02);
54 // give the sensor time to set up:
55 delay(100);
56 }
57
58 void loop() {
59 //Select High Resolution Mode
60 writeRegister(0x03, 0x0A);
61
62 // don't do anything until the data ready pin is high:
63 if (digitalRead(dataReadyPin) == HIGH) {
64 //Read the temperature data
65 int tempData = readRegister(0x21, 2);
66
67 // convert the temperature to celsius and display it:
68 float realTemp = (float)tempData / 20.0;
69 Serial.print("Temp[C]=");
70 Serial.print(realTemp);
71
72
73 //Read the pressure data highest 3 bits:
74 byte pressure_data_high = readRegister(0x1F, 1);
75 pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
76
77 //Read the pressure data lower 16 bits:
78 unsigned int pressure_data_low = readRegister(0x20, 2);
79 //combine the two parts into one 19-bit number:
80 long pressure = ((pressure_data_high << 16) | pressure_data_low)/4;
81
82 // display the temperature:
83 Serial.println("\tPressure [Pa]=" + String(pressure));
84 }
85 }
86
87 //Read from or write to register from the SCP1000:
88 unsigned int readRegister(byte thisRegister, int bytesToRead ) {
89 byte inByte = 0; // incoming byte from the SPI
90 unsigned int result = 0; // result to return
91 Serial.print(thisRegister, BIN);
92 Serial.print("\t");
93 // SCP1000 expects the register name in the upper 6 bits
94 // of the byte. So shift the bits left by two bits:
95 thisRegister = thisRegister << 2;
96 // now combine the address and the command into one byte
97 byte dataToSend = thisRegister & READ;
98 Serial.println(thisRegister, BIN);
99 // take the chip select low to select the device:
100 digitalWrite(chipSelectPin, LOW);
101 // send the device the register you want to read:
102 SPI.transfer(dataToSend);
103 // send a value of 0 to read the first byte returned:
104 result = SPI.transfer(0x00);
105 // decrement the number of bytes left to read:
106 bytesToRead--;
107 // if you still have another byte to read:
108 if (bytesToRead > 0) {
109 // shift the first byte left, then get the second byte:
110 result = result << 8;
111 inByte = SPI.transfer(0x00);
112 // combine the byte you just got with the previous one:
113 result = result | inByte;
114 // decrement the number of bytes left to read:
115 bytesToRead--;
116 }
117 // take the chip select high to de-select:
118 digitalWrite(chipSelectPin, HIGH);
119 // return the result:
120 return(result);
121 }
122
123
124 //Sends a write command to SCP1000
125
126 void writeRegister(byte thisRegister, byte thisValue) {
127
128 // SCP1000 expects the register address in the upper 6 bits
129 // of the byte. So shift the bits left by two bits:
130 thisRegister = thisRegister << 2;
131 // now combine the register address and the command into one byte:
132 byte dataToSend = thisRegister | WRITE;
133
134 // take the chip select low to select the device:
135 digitalWrite(chipSelectPin, LOW);
136
137 SPI.transfer(dataToSend); //Send register location
138 SPI.transfer(thisValue); //Send value to record into register
139
140 // take the chip select high to de-select:
141 digitalWrite(chipSelectPin, HIGH);
142 }
143
@@ -0,0 +1,71
1 /*
2 Digital Pot Control
3
4 This example controls an Analog Devices AD5206 digital potentiometer.
5 The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
6 A - connect this to voltage
7 W - this is the pot's wiper, which changes when you set it
8 B - connect this to ground.
9
10 The AD5206 is SPI-compatible,and to command it, you send two bytes,
11 one with the channel number (0 - 5) and one with the resistance value for the
12 channel (0 - 255).
13
14 The circuit:
15 * All A pins of AD5206 connected to +5V
16 * All B pins of AD5206 connected to ground
17 * An LED and a 220-ohm resisor in series connected from each W pin to ground
18 * CS - to digital pin 10 (SS pin)
19 * SDI - to digital pin 11 (MOSI pin)
20 * CLK - to digital pin 13 (SCK pin)
21
22 created 10 Aug 2010
23 by Tom Igoe
24
25 Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
26
27 */
28
29
30 // inslude the SPI library:
31 #include <SPI.h>
32
33
34 // set pin 10 as the slave select for the digital pot:
35 const int slaveSelectPin = 10;
36
37 void setup() {
38 // set the slaveSelectPin as an output:
39 pinMode (slaveSelectPin, OUTPUT);
40 // initialize SPI:
41 SPI.begin();
42 }
43
44 void loop() {
45 // go through the six channels of the digital pot:
46 for (int channel = 0; channel < 6; channel++) {
47 // change the resistance on this channel from min to max:
48 for (int level = 0; level < 255; level++) {
49 digitalPotWrite(channel, level);
50 delay(10);
51 }
52 // wait a second at the top:
53 delay(100);
54 // change the resistance on this channel from max to min:
55 for (int level = 0; level < 255; level++) {
56 digitalPotWrite(channel, 255 - level);
57 delay(10);
58 }
59 }
60
61 }
62
63 void digitalPotWrite(int address, int value) {
64 // take the SS pin low to select the chip:
65 digitalWrite(slaveSelectPin,LOW);
66 // send in the address and value via SPI:
67 SPI.transfer(address);
68 SPI.transfer(value);
69 // take the SS pin high to de-select the chip:
70 digitalWrite(slaveSelectPin,HIGH);
71 }
@@ -0,0 +1,36
1 #######################################
2 # Syntax Coloring Map SPI
3 #######################################
4
5 #######################################
6 # Datatypes (KEYWORD1)
7 #######################################
8
9 SPI KEYWORD1
10
11 #######################################
12 # Methods and Functions (KEYWORD2)
13 #######################################
14 begin KEYWORD2
15 end KEYWORD2
16 transfer KEYWORD2
17 setBitOrder KEYWORD2
18 setDataMode KEYWORD2
19 setClockDivider KEYWORD2
20
21
22 #######################################
23 # Constants (LITERAL1)
24 #######################################
25 SPI_CLOCK_DIV4 LITERAL1
26 SPI_CLOCK_DIV16 LITERAL1
27 SPI_CLOCK_DIV64 LITERAL1
28 SPI_CLOCK_DIV128 LITERAL1
29 SPI_CLOCK_DIV2 LITERAL1
30 SPI_CLOCK_DIV8 LITERAL1
31 SPI_CLOCK_DIV32 LITERAL1
32 SPI_CLOCK_DIV64 LITERAL1
33 SPI_MODE0 LITERAL1
34 SPI_MODE1 LITERAL1
35 SPI_MODE2 LITERAL1
36 SPI_MODE3 LITERAL1 No newline at end of file
@@ -0,0 +1,97
1 /* DateStrings.cpp
2 * Definitions for date strings for use with the Time library
3 *
4 * Updated for Arduino 1.5.7 18 July 2014
5 *
6 * No memory is consumed in the sketch if your code does not call any of the string methods
7 * You can change the text of the strings, make sure the short strings are each exactly 3 characters
8 * the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in Time.h
9 *
10 */
11
12 #if defined(__AVR__)
13 #include <avr/pgmspace.h>
14 #else
15 // for compatiblity with Arduino Due and Teensy 3.0 and maybe others?
16 #define PROGMEM
17 #define PGM_P const char *
18 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
19 #define pgm_read_word(addr) (*(const unsigned char **)(addr))
20 #define strcpy_P(dest, src) strcpy((dest), (src))
21 #endif
22 #include <string.h> // for strcpy_P or strcpy
23 #include "Time.h"
24
25 // the short strings for each day or month must be exactly dt_SHORT_STR_LEN
26 #define dt_SHORT_STR_LEN 3 // the length of short strings
27
28 static char buffer[dt_MAX_STRING_LEN+1]; // must be big enough for longest string and the terminating null
29
30 const char monthStr0[] PROGMEM = "";
31 const char monthStr1[] PROGMEM = "January";
32 const char monthStr2[] PROGMEM = "February";
33 const char monthStr3[] PROGMEM = "March";
34 const char monthStr4[] PROGMEM = "April";
35 const char monthStr5[] PROGMEM = "May";
36 const char monthStr6[] PROGMEM = "June";
37 const char monthStr7[] PROGMEM = "July";
38 const char monthStr8[] PROGMEM = "August";
39 const char monthStr9[] PROGMEM = "September";
40 const char monthStr10[] PROGMEM = "October";
41 const char monthStr11[] PROGMEM = "November";
42 const char monthStr12[] PROGMEM = "December";
43
44 const PROGMEM char * const PROGMEM monthNames_P[] =
45 {
46 monthStr0,monthStr1,monthStr2,monthStr3,monthStr4,monthStr5,monthStr6,
47 monthStr7,monthStr8,monthStr9,monthStr10,monthStr11,monthStr12
48 };
49
50 const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec";
51
52 const char dayStr0[] PROGMEM = "Err";
53 const char dayStr1[] PROGMEM = "Sunday";
54 const char dayStr2[] PROGMEM = "Monday";
55 const char dayStr3[] PROGMEM = "Tuesday";
56 const char dayStr4[] PROGMEM = "Wednesday";
57 const char dayStr5[] PROGMEM = "Thursday";
58 const char dayStr6[] PROGMEM = "Friday";
59 const char dayStr7[] PROGMEM = "Saturday";
60
61 const PROGMEM char * const PROGMEM dayNames_P[] =
62 {
63 dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7
64 };
65
66 const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat";
67
68 /* functions to return date strings */
69
70 char* monthStr(uint8_t month)
71 {
72 strcpy_P(buffer, (PGM_P)pgm_read_word(&(monthNames_P[month])));
73 return buffer;
74 }
75
76 char* monthShortStr(uint8_t month)
77 {
78 for (int i=0; i < dt_SHORT_STR_LEN; i++)
79 buffer[i] = pgm_read_byte(&(monthShortNames_P[i+ (month*dt_SHORT_STR_LEN)]));
80 buffer[dt_SHORT_STR_LEN] = 0;
81 return buffer;
82 }
83
84 char* dayStr(uint8_t day)
85 {
86 strcpy_P(buffer, (PGM_P)pgm_read_word(&(dayNames_P[day])));
87 return buffer;
88 }
89
90 char* dayShortStr(uint8_t day)
91 {
92 uint8_t index = day*dt_SHORT_STR_LEN;
93 for (int i=0; i < dt_SHORT_STR_LEN; i++)
94 buffer[i] = pgm_read_byte(&(dayShortNames_P[index + i]));
95 buffer[dt_SHORT_STR_LEN] = 0;
96 return buffer;
97 }
@@ -0,0 +1,131
1 Readme file for Arduino Time Library
2
3 Time is a library that provides timekeeping functionality for Arduino.
4
5 The code is derived from the Playground DateTime library but is updated
6 to provide an API that is more flexable and easier to use.
7
8 A primary goal was to enable date and time functionality that can be used with
9 a variety of external time sources with minimum differences required in sketch logic.
10
11 Example sketches illustrate how similar sketch code can be used with: a Real Time Clock,
12 internet NTP time service, GPS time data, and Serial time messages from a computer
13 for time synchronization.
14
15 The functions available in the library include:
16
17 hour(); // the hour now (0-23)
18 minute(); // the minute now (0-59)
19 second(); // the second now (0-59)
20 day(); // the day now (1-31)
21 weekday(); // day of the week, Sunday is day 0
22 month(); // the month now (1-12)
23 year(); // the full four digit year: (2009, 2010 etc)
24
25 there are also functions to return the hour in 12 hour format
26 hourFormat12(); // the hour now in 12 hour format
27 isAM(); // returns true if time now is AM
28 isPM(); // returns true if time now is PM
29
30 now(); // returns the current time as seconds since Jan 1 1970
31
32 The time and date functions can take an optional parameter for the time. This prevents
33 errors if the time rolls over between elements. For example, if a new minute begins
34 between getting the minute and second, the values will be inconsistent. Using the
35 following functions eliminates this probglem
36 time_t t = now(); // store the current time in time variable t
37 hour(t); // returns the hour for the given time t
38 minute(t); // returns the minute for the given time t
39 second(t); // returns the second for the given time t
40 day(t); // the day for the given time t
41 weekday(t); // day of the week for the given time t
42 month(t); // the month for the given time t
43 year(t); // the year for the given time t
44
45
46 Functions for managing the timer services are:
47 setTime(t); // set the system time to the give time t
48 setTime(hr,min,sec,day,mnth,yr); // alternative to above, yr is 2 or 4 digit yr (2010 or 10 sets year to 2010)
49 adjustTime(adjustment); // adjust system time by adding the adjustment value
50
51 timeStatus(); // indicates if time has been set and recently synchronized
52 // returns one of the following enumerations:
53 timeNotSet // the time has never been set, the clock started at Jan 1 1970
54 timeNeedsSync // the time had been set but a sync attempt did not succeed
55 timeSet // the time is set and is synced
56 Time and Date values are not valid if the status is timeNotSet. Otherwise values can be used but
57 the returned time may have drifted if the status is timeNeedsSync.
58
59 setSyncProvider(getTimeFunction); // set the external time provider
60 setSyncInterval(interval); // set the number of seconds between re-sync
61
62
63 There are many convenience macros in the time.h file for time constants and conversion of time units.
64
65 To use the library, copy the download to the Library directory.
66
67 The Time directory contains the Time library and some example sketches
68 illustrating how the library can be used with various time sources:
69
70 - TimeSerial.pde shows Arduino as a clock without external hardware.
71 It is synchronized by time messages sent over the serial port.
72 A companion Processing sketch will automatically provide these messages
73 if it is running and connected to the Arduino serial port.
74
75 - TimeSerialDateStrings.pde adds day and month name strings to the sketch above
76 Short (3 character) and long strings are available to print the days of
77 the week and names of the months.
78
79 - TimeRTC uses a DS1307 real time clock to provide time synchronization.
80 A basic RTC library named DS1307RTC is included in the download.
81 To run this sketch the DS1307RTC library must be installed.
82
83 - TimeRTCSet is similar to the above and adds the ability to set the Real Time Clock
84
85 - TimeRTCLog demonstrates how to calculate the difference between times.
86 It is a vary simple logger application that monitors events on digtial pins
87 and prints (to the serial port) the time of an event and the time period since the previous event.
88
89 - TimeNTP uses the Arduino Ethernet shield to access time using the internet NTP time service.
90 The NTP protocol uses UDP and the UdpBytewise library is required, see:
91 http://bitbucket.org/bjoern/arduino_osc/src/14667490521f/libraries/Ethernet/
92
93 - TimeGPS gets time from a GPS
94 This requires the TinyGPS library from Mikal Hart:
95 http://arduiniana.org/libraries/TinyGPS
96
97 Differences between this code and the playground DateTime library
98 although the Time library is based on the DateTime codebase, the API has changed.
99 Changes in the Time library API:
100 - time elements are functions returning int (they are variables in DateTime)
101 - Years start from 1970
102 - days of the week and months start from 1 (they start from 0 in DateTime)
103 - DateStrings do not require a seperate library
104 - time elements can be accessed non-atomically (in DateTime they are always atomic)
105 - function added to automatically sync time with extrnal source
106 - localTime and maketime parameters changed, localTime renamed to breakTime
107
108 Technical notes:
109
110 Internal system time is based on the standard Unix time_t.
111 The value is the number of seconds since Jan 1 1970.
112 System time begins at zero when the sketch starts.
113
114 The internal time can be automatically synchronized at regular intervals to an external time source.
115 This is enabled by calling the setSyncProvider(provider) function - the provider argument is
116 the address of a function that returns the current time as a time_t.
117 See the sketches in the examples directory for usage.
118
119 The default interval for re-syncing the time is 5 minutes but can be changed by calling the
120 setSyncInterval( interval) method to set the number of seconds between re-sync attempts.
121
122 The Time library defines a structure for holding time elements that is a compact version of the C tm structure.
123 All the members of the Arduino tm structure are bytes and the year is offset from 1970.
124 Convenience macros provide conversion to and from the Arduino format.
125
126 Low level functions to convert between system time and individual time elements are provided:
127 breakTime( time, &tm); // break time_t into elements stored in tm struct
128 makeTime( &tm); // return time_t from elements stored in tm struct
129
130 The DS1307RTC library included in the download provides an example of how a time provider
131 can use the low level functions to interface with the Time library.
@@ -0,0 +1,319
1 /*
2 time.c - low level time and date functions
3 Copyright (c) Michael Margolis 2009-2014
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 1.0 6 Jan 2010 - initial release
20 1.1 12 Feb 2010 - fixed leap year calculation error
21 1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this)
22 1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update
23 status, updated examples for Arduino 1.0, fixed ARM
24 compatibility issues, added TimeArduinoDue and TimeTeensy3
25 examples, add error checking and messages to RTC examples,
26 add examples to DS1307RTC library.
27 1.4 5 Sep 2014 - compatibility with Arduino 1.5.7
28 */
29
30 #if ARDUINO >= 100
31 #include <Arduino.h>
32 #else
33 #include <WProgram.h>
34 #endif
35
36 #include "Time.h"
37
38 static tmElements_t tm; // a cache of time elements
39 static time_t cacheTime; // the time the cache was updated
40 static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds
41
42 void refreshCache(time_t t) {
43 if (t != cacheTime) {
44 breakTime(t, tm);
45 cacheTime = t;
46 }
47 }
48
49 int hour() { // the hour now
50 return hour(now());
51 }
52
53 int hour(time_t t) { // the hour for the given time
54 refreshCache(t);
55 return tm.Hour;
56 }
57
58 int hourFormat12() { // the hour now in 12 hour format
59 return hourFormat12(now());
60 }
61
62 int hourFormat12(time_t t) { // the hour for the given time in 12 hour format
63 refreshCache(t);
64 if( tm.Hour == 0 )
65 return 12; // 12 midnight
66 else if( tm.Hour > 12)
67 return tm.Hour - 12 ;
68 else
69 return tm.Hour ;
70 }
71
72 uint8_t isAM() { // returns true if time now is AM
73 return !isPM(now());
74 }
75
76 uint8_t isAM(time_t t) { // returns true if given time is AM
77 return !isPM(t);
78 }
79
80 uint8_t isPM() { // returns true if PM
81 return isPM(now());
82 }
83
84 uint8_t isPM(time_t t) { // returns true if PM
85 return (hour(t) >= 12);
86 }
87
88 int minute() {
89 return minute(now());
90 }
91
92 int minute(time_t t) { // the minute for the given time
93 refreshCache(t);
94 return tm.Minute;
95 }
96
97 int second() {
98 return second(now());
99 }
100
101 int second(time_t t) { // the second for the given time
102 refreshCache(t);
103 return tm.Second;
104 }
105
106 int day(){
107 return(day(now()));
108 }
109
110 int day(time_t t) { // the day for the given time (0-6)
111 refreshCache(t);
112 return tm.Day;
113 }
114
115 int weekday() { // Sunday is day 1
116 return weekday(now());
117 }
118
119 int weekday(time_t t) {
120 refreshCache(t);
121 return tm.Wday;
122 }
123
124 int month(){
125 return month(now());
126 }
127
128 int month(time_t t) { // the month for the given time
129 refreshCache(t);
130 return tm.Month;
131 }
132
133 int year() { // as in Processing, the full four digit year: (2009, 2010 etc)
134 return year(now());
135 }
136
137 int year(time_t t) { // the year for the given time
138 refreshCache(t);
139 return tmYearToCalendar(tm.Year);
140 }
141
142 /*============================================================================*/
143 /* functions to convert to and from system time */
144 /* These are for interfacing with time serivces and are not normally needed in a sketch */
145
146 // leap year calulator expects year argument as years offset from 1970
147 #define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
148
149 static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0
150
151 void breakTime(time_t timeInput, tmElements_t &tm){
152 // break the given time_t into time components
153 // this is a more compact version of the C library localtime function
154 // note that year is offset from 1970 !!!
155
156 uint8_t year;
157 uint8_t month, monthLength;
158 uint32_t time;
159 unsigned long days;
160
161 time = (uint32_t)timeInput;
162 tm.Second = time % 60;
163 time /= 60; // now it is minutes
164 tm.Minute = time % 60;
165 time /= 60; // now it is hours
166 tm.Hour = time % 24;
167 time /= 24; // now it is days
168 tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1
169
170 year = 0;
171 days = 0;
172 while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
173 year++;
174 }
175 tm.Year = year; // year is offset from 1970
176
177 days -= LEAP_YEAR(year) ? 366 : 365;
178 time -= days; // now it is days in this year, starting at 0
179
180 days=0;
181 month=0;
182 monthLength=0;
183 for (month=0; month<12; month++) {
184 if (month==1) { // february
185 if (LEAP_YEAR(year)) {
186 monthLength=29;
187 } else {
188 monthLength=28;
189 }
190 } else {
191 monthLength = monthDays[month];
192 }
193
194 if (time >= monthLength) {
195 time -= monthLength;
196 } else {
197 break;
198 }
199 }
200 tm.Month = month + 1; // jan is month 1
201 tm.Day = time + 1; // day of month
202 }
203
204 time_t makeTime(tmElements_t &tm){
205 // assemble time elements into time_t
206 // note year argument is offset from 1970 (see macros in time.h to convert to other formats)
207 // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
208
209 int i;
210 uint32_t seconds;
211
212 // seconds from 1970 till 1 jan 00:00:00 of the given year
213 seconds= tm.Year*(SECS_PER_DAY * 365);
214 for (i = 0; i < tm.Year; i++) {
215 if (LEAP_YEAR(i)) {
216 seconds += SECS_PER_DAY; // add extra days for leap years
217 }
218 }
219
220 // add days for this year, months start from 1
221 for (i = 1; i < tm.Month; i++) {
222 if ( (i == 2) && LEAP_YEAR(tm.Year)) {
223 seconds += SECS_PER_DAY * 29;
224 } else {
225 seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0
226 }
227 }
228 seconds+= (tm.Day-1) * SECS_PER_DAY;
229 seconds+= tm.Hour * SECS_PER_HOUR;
230 seconds+= tm.Minute * SECS_PER_MIN;
231 seconds+= tm.Second;
232 return (time_t)seconds;
233 }
234 /*=====================================================*/
235 /* Low level system time functions */
236
237 static uint32_t sysTime = 0;
238 static uint32_t prevMillis = 0;
239 static uint32_t nextSyncTime = 0;
240 static timeStatus_t Status = timeNotSet;
241
242 getExternalTime getTimePtr; // pointer to external sync function
243 //setExternalTime setTimePtr; // not used in this version
244
245 #ifdef TIME_DRIFT_INFO // define this to get drift data
246 time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync
247 #endif
248
249
250 time_t now() {
251 while (millis() - prevMillis >= 1000){
252 sysTime++;
253 prevMillis += 1000;
254 #ifdef TIME_DRIFT_INFO
255 sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift
256 #endif
257 }
258 if (nextSyncTime <= sysTime) {
259 if (getTimePtr != 0) {
260 time_t t = getTimePtr();
261 if (t != 0) {
262 setTime(t);
263 } else {
264 nextSyncTime = sysTime + syncInterval;
265 Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync;
266 }
267 }
268 }
269 return (time_t)sysTime;
270 }
271
272 void setTime(time_t t) {
273 #ifdef TIME_DRIFT_INFO
274 if(sysUnsyncedTime == 0)
275 sysUnsyncedTime = t; // store the time of the first call to set a valid Time
276 #endif
277
278 sysTime = (uint32_t)t;
279 nextSyncTime = (uint32_t)t + syncInterval;
280 Status = timeSet;
281 prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
282 }
283
284 void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
285 // year can be given as full four digit year or two digts (2010 or 10 for 2010);
286 //it is converted to years since 1970
287 if( yr > 99)
288 yr = yr - 1970;
289 else
290 yr += 30;
291 tm.Year = yr;
292 tm.Month = mnth;
293 tm.Day = dy;
294 tm.Hour = hr;
295 tm.Minute = min;
296 tm.Second = sec;
297 setTime(makeTime(tm));
298 }
299
300 void adjustTime(long adjustment) {
301 sysTime += adjustment;
302 }
303
304 // indicates if time has been set and recently synchronized
305 timeStatus_t timeStatus() {
306 now(); // required to actually update the status
307 return Status;
308 }
309
310 void setSyncProvider( getExternalTime getTimeFunction){
311 getTimePtr = getTimeFunction;
312 nextSyncTime = sysTime;
313 now(); // this will sync the clock
314 }
315
316 void setSyncInterval(time_t interval){ // set the number of seconds between re-sync
317 syncInterval = (uint32_t)interval;
318 nextSyncTime = sysTime + syncInterval;
319 }
@@ -0,0 +1,144
1 /*
2 time.h - low level time and date functions
3 */
4
5 /*
6 July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this)
7 - fixed daysToTime_t macro (thanks maniacbug)
8 */
9
10 #ifndef _Time_h
11 #ifdef __cplusplus
12 #define _Time_h
13
14 #include <inttypes.h>
15 #ifndef __AVR__
16 #include <sys/types.h> // for __time_t_defined, but avr libc lacks sys/types.h
17 #endif
18
19
20 #if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc
21 typedef unsigned long time_t;
22 #endif
23
24
25 // This ugly hack allows us to define C++ overloaded functions, when included
26 // from within an extern "C", as newlib's sys/stat.h does. Actually it is
27 // intended to include "time.h" from the C library (on ARM, but AVR does not
28 // have that file at all). On Mac and Windows, the compiler will find this
29 // "Time.h" instead of the C library "time.h", so we may cause other weird
30 // and unpredictable effects by conflicting with the C library header "time.h",
31 // but at least this hack lets us define C++ functions as intended. Hopefully
32 // nothing too terrible will result from overriding the C library header?!
33 extern "C++" {
34 typedef enum {timeNotSet, timeNeedsSync, timeSet
35 } timeStatus_t ;
36
37 typedef enum {
38 dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday
39 } timeDayOfWeek_t;
40
41 typedef enum {
42 tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields
43 } tmByteFields;
44
45 typedef struct {
46 uint8_t Second;
47 uint8_t Minute;
48 uint8_t Hour;
49 uint8_t Wday; // day of week, sunday is day 1
50 uint8_t Day;
51 uint8_t Month;
52 uint8_t Year; // offset from 1970;
53 } tmElements_t, TimeElements, *tmElementsPtr_t;
54
55 //convenience macros to convert to and from tm years
56 #define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year
57 #define CalendarYrToTm(Y) ((Y) - 1970)
58 #define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000
59 #define y2kYearToTm(Y) ((Y) + 30)
60
61 typedef time_t(*getExternalTime)();
62 //typedef void (*setExternalTime)(const time_t); // not used in this version
63
64
65 /*==============================================================================*/
66 /* Useful Constants */
67 #define SECS_PER_MIN (60UL)
68 #define SECS_PER_HOUR (3600UL)
69 #define SECS_PER_DAY (SECS_PER_HOUR * 24UL)
70 #define DAYS_PER_WEEK (7UL)
71 #define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
72 #define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
73 #define SECS_YR_2000 (946684800UL) // the time at the start of y2k
74
75 /* Useful Macros for getting elapsed time */
76 #define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
77 #define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
78 #define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
79 #define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday
80 #define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970
81 #define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight
82 // The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
83 // Always set the correct time before settting alarms
84 #define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
85 #define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day
86 #define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1
87 #define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time
88 #define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time
89
90
91 /* Useful Macros for converting elapsed time to a time_t */
92 #define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN)
93 #define hoursToTime_t ((H)) ( (H) * SECS_PER_HOUR)
94 #define daysToTime_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
95 #define weeksToTime_t ((W)) ( (W) * SECS_PER_WEEK)
96
97 /*============================================================================*/
98 /* time and date functions */
99 int hour(); // the hour now
100 int hour(time_t t); // the hour for the given time
101 int hourFormat12(); // the hour now in 12 hour format
102 int hourFormat12(time_t t); // the hour for the given time in 12 hour format
103 uint8_t isAM(); // returns true if time now is AM
104 uint8_t isAM(time_t t); // returns true the given time is AM
105 uint8_t isPM(); // returns true if time now is PM
106 uint8_t isPM(time_t t); // returns true the given time is PM
107 int minute(); // the minute now
108 int minute(time_t t); // the minute for the given time
109 int second(); // the second now
110 int second(time_t t); // the second for the given time
111 int day(); // the day now
112 int day(time_t t); // the day for the given time
113 int weekday(); // the weekday now (Sunday is day 1)
114 int weekday(time_t t); // the weekday for the given time
115 int month(); // the month now (Jan is month 1)
116 int month(time_t t); // the month for the given time
117 int year(); // the full four digit year: (2009, 2010 etc)
118 int year(time_t t); // the year for the given time
119
120 time_t now(); // return the current time as seconds since Jan 1 1970
121 void setTime(time_t t);
122 void setTime(int hr,int min,int sec,int day, int month, int yr);
123 void adjustTime(long adjustment);
124
125 /* date strings */
126 #define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null)
127 char* monthStr(uint8_t month);
128 char* dayStr(uint8_t day);
129 char* monthShortStr(uint8_t month);
130 char* dayShortStr(uint8_t day);
131
132 /* time sync functions */
133 timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized
134 void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider
135 void setSyncInterval(time_t interval); // set the number of seconds between re-sync
136
137 /* low level functions to convert to and from system time */
138 void breakTime(time_t time, tmElements_t &tm); // break time_t into elements
139 time_t makeTime(tmElements_t &tm); // convert time elements into time_t
140
141 } // extern "C++"
142 #endif // __cplusplus
143 #endif /* _Time_h */
144
@@ -0,0 +1,33
1 #######################################
2 # Syntax Coloring Map For Time
3 #######################################
4
5 #######################################
6 # Datatypes (KEYWORD1)
7 #######################################
8 time_t KEYWORD1
9 #######################################
10 # Methods and Functions (KEYWORD2)
11 #######################################
12 now KEYWORD2
13 second KEYWORD2
14 minute KEYWORD2
15 hour KEYWORD2
16 day KEYWORD2
17 month KEYWORD2
18 year KEYWORD2
19 isAM KEYWORD2
20 isPM KEYWORD2
21 weekday KEYWORD2
22 setTime KEYWORD2
23 adjustTime KEYWORD2
24 setSyncProvider KEYWORD2
25 setSyncInterval KEYWORD2
26 timeStatus KEYWORD2
27 #######################################
28 # Instances (KEYWORD2)
29 #######################################
30
31 #######################################
32 # Constants (LITERAL1)
33 #######################################
@@ -0,0 +1,22
1 {
2 "name": "Time",
3 "frameworks": "Arduino",
4 "keywords": "Time, date, hour, minute, second, day, week, month, year, RTC",
5 "description": "Time keeping library",
6 "url": "http://playground.arduino.cc/Code/Time",
7 "authors":
8 [
9 {
10 "name": "Michael Margolis"
11 },
12 {
13 "name": "Paul Stoffregen"
14 }
15 ],
16 "repository":
17 {
18 "type": "git",
19 "url": "https://github.com/PaulStoffregen/Time"
20 }
21 }
22
@@ -0,0 +1,298
1 /*
2 TwoWire.cpp - TWI/I2C library for Wiring & Arduino
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
20 */
21
22 extern "C" {
23 #include <stdlib.h>
24 #include <string.h>
25 #include <inttypes.h>
26 #include <twi.h>
27 }
28
29 #include "Wire.h"
30
31 // Initialize Class Variables //////////////////////////////////////////////////
32
33 uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
34 uint8_t TwoWire::rxBufferIndex = 0;
35 uint8_t TwoWire::rxBufferLength = 0;
36
37 uint8_t TwoWire::txAddress = 0;
38 uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
39 uint8_t TwoWire::txBufferIndex = 0;
40 uint8_t TwoWire::txBufferLength = 0;
41
42 uint8_t TwoWire::transmitting = 0;
43 void (*TwoWire::user_onRequest)(void);
44 void (*TwoWire::user_onReceive)(int);
45
46 // Constructors ////////////////////////////////////////////////////////////////
47
48 TwoWire::TwoWire()
49 {
50 }
51
52 // Public Methods //////////////////////////////////////////////////////////////
53
54 void TwoWire::begin(void)
55 {
56 rxBufferIndex = 0;
57 rxBufferLength = 0;
58
59 txBufferIndex = 0;
60 txBufferLength = 0;
61
62 twi_init();
63 }
64
65 void TwoWire::begin(uint8_t address)
66 {
67 twi_setAddress(address);
68 twi_attachSlaveTxEvent(onRequestService);
69 twi_attachSlaveRxEvent(onReceiveService);
70 begin();
71 }
72
73 void TwoWire::begin(int address)
74 {
75 begin((uint8_t)address);
76 }
77
78 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
79 {
80 // clamp to buffer length
81 if(quantity > BUFFER_LENGTH){
82 quantity = BUFFER_LENGTH;
83 }
84 // perform blocking read into buffer
85 uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
86 // set rx buffer iterator vars
87 rxBufferIndex = 0;
88 rxBufferLength = read;
89
90 return read;
91 }
92
93 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
94 {
95 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
96 }
97
98 uint8_t TwoWire::requestFrom(int address, int quantity)
99 {
100 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
101 }
102
103 uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
104 {
105 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
106 }
107
108 void TwoWire::beginTransmission(uint8_t address)
109 {
110 // indicate that we are transmitting
111 transmitting = 1;
112 // set address of targeted slave
113 txAddress = address;
114 // reset tx buffer iterator vars
115 txBufferIndex = 0;
116 txBufferLength = 0;
117 }
118
119 void TwoWire::beginTransmission(int address)
120 {
121 beginTransmission((uint8_t)address);
122 }
123
124 //
125 // Originally, 'endTransmission' was an f(void) function.
126 // It has been modified to take one parameter indicating
127 // whether or not a STOP should be performed on the bus.
128 // Calling endTransmission(false) allows a sketch to
129 // perform a repeated start.
130 //
131 // WARNING: Nothing in the library keeps track of whether
132 // the bus tenure has been properly ended with a STOP. It
133 // is very possible to leave the bus in a hung state if
134 // no call to endTransmission(true) is made. Some I2C
135 // devices will behave oddly if they do not see a STOP.
136 //
137 uint8_t TwoWire::endTransmission(uint8_t sendStop)
138 {
139 // transmit buffer (blocking)
140 int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
141 // reset tx buffer iterator vars
142 txBufferIndex = 0;
143 txBufferLength = 0;
144 // indicate that we are done transmitting
145 transmitting = 0;
146 return ret;
147 }
148
149 // This provides backwards compatibility with the original
150 // definition, and expected behaviour, of endTransmission
151 //
152 uint8_t TwoWire::endTransmission(void)
153 {
154 return endTransmission(true);
155 }
156
157 // must be called in:
158 // slave tx event callback
159 // or after beginTransmission(address)
160 size_t TwoWire::write(uint8_t data)
161 {
162 if(transmitting){
163 // in master transmitter mode
164 // don't bother if buffer is full
165 if(txBufferLength >= BUFFER_LENGTH){
166 setWriteError();
167 return 0;
168 }
169 // put byte in tx buffer
170 txBuffer[txBufferIndex] = data;
171 ++txBufferIndex;
172 // update amount in buffer
173 txBufferLength = txBufferIndex;
174 }else{
175 // in slave send mode
176 // reply to master
177 twi_transmit(&data, 1);
178 }
179 return 1;
180 }
181
182 // must be called in:
183 // slave tx event callback
184 // or after beginTransmission(address)
185 size_t TwoWire::write(const uint8_t *data, size_t quantity)
186 {
187 if(transmitting){
188 // in master transmitter mode
189 for(size_t i = 0; i < quantity; ++i){
190 write(data[i]);
191 }
192 }else{
193 // in slave send mode
194 // reply to master
195 twi_transmit(data, quantity);
196 }
197 return quantity;
198 }
199
200 // must be called in:
201 // slave rx event callback
202 // or after requestFrom(address, numBytes)
203 int TwoWire::available(void)
204 {
205 return rxBufferLength - rxBufferIndex;
206 }
207
208 // must be called in:
209 // slave rx event callback
210 // or after requestFrom(address, numBytes)
211 int TwoWire::read(void)
212 {
213 int value = -1;
214
215 // get each successive byte on each call
216 if(rxBufferIndex < rxBufferLength){
217 value = rxBuffer[rxBufferIndex];
218 ++rxBufferIndex;
219 }
220
221 return value;
222 }
223
224 // must be called in:
225 // slave rx event callback
226 // or after requestFrom(address, numBytes)
227 int TwoWire::peek(void)
228 {
229 int value = -1;
230
231 if(rxBufferIndex < rxBufferLength){
232 value = rxBuffer[rxBufferIndex];
233 }
234
235 return value;
236 }
237
238 void TwoWire::flush(void)
239 {
240 // XXX: to be implemented.
241 }
242
243 // behind the scenes function that is called when data is received
244 void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
245 {
246 // don't bother if user hasn't registered a callback
247 if(!user_onReceive){
248 return;
249 }
250 // don't bother if rx buffer is in use by a master requestFrom() op
251 // i know this drops data, but it allows for slight stupidity
252 // meaning, they may not have read all the master requestFrom() data yet
253 if(rxBufferIndex < rxBufferLength){
254 return;
255 }
256 // copy twi rx buffer into local read buffer
257 // this enables new reads to happen in parallel
258 for(uint8_t i = 0; i < numBytes; ++i){
259 rxBuffer[i] = inBytes[i];
260 }
261 // set rx iterator vars
262 rxBufferIndex = 0;
263 rxBufferLength = numBytes;
264 // alert user program
265 user_onReceive(numBytes);
266 }
267
268 // behind the scenes function that is called when data is requested
269 void TwoWire::onRequestService(void)
270 {
271 // don't bother if user hasn't registered a callback
272 if(!user_onRequest){
273 return;
274 }
275 // reset tx buffer iterator vars
276 // !!! this will kill any pending pre-master sendTo() activity
277 txBufferIndex = 0;
278 txBufferLength = 0;
279 // alert user program
280 user_onRequest();
281 }
282
283 // sets function called on slave write
284 void TwoWire::onReceive( void (*function)(int) )
285 {
286 user_onReceive = function;
287 }
288
289 // sets function called on slave read
290 void TwoWire::onRequest( void (*function)(void) )
291 {
292 user_onRequest = function;
293 }
294
295 // Preinstantiate Objects //////////////////////////////////////////////////////
296
297 TwoWire Wire = TwoWire();
298
@@ -0,0 +1,79
1 /*
2 TwoWire.h - TWI/I2C library for Arduino & Wiring
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
20 */
21
22 #ifndef TwoWire_h
23 #define TwoWire_h
24
25 #include <inttypes.h>
26 #include "Stream.h"
27
28 #define BUFFER_LENGTH 32
29
30 class TwoWire : public Stream
31 {
32 private:
33 static uint8_t rxBuffer[];
34 static uint8_t rxBufferIndex;
35 static uint8_t rxBufferLength;
36
37 static uint8_t txAddress;
38 static uint8_t txBuffer[];
39 static uint8_t txBufferIndex;
40 static uint8_t txBufferLength;
41
42 static uint8_t transmitting;
43 static void (*user_onRequest)(void);
44 static void (*user_onReceive)(int);
45 static void onRequestService(void);
46 static void onReceiveService(uint8_t*, int);
47 public:
48 TwoWire();
49 void begin();
50 void begin(uint8_t);
51 void begin(int);
52 void beginTransmission(uint8_t);
53 void beginTransmission(int);
54 uint8_t endTransmission(void);
55 uint8_t endTransmission(uint8_t);
56 uint8_t requestFrom(uint8_t, uint8_t);
57 uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
58 uint8_t requestFrom(int, int);
59 uint8_t requestFrom(int, int, int);
60 virtual size_t write(uint8_t);
61 virtual size_t write(const uint8_t *, size_t);
62 virtual int available(void);
63 virtual int read(void);
64 virtual int peek(void);
65 virtual void flush(void);
66 void onReceive( void (*)(int) );
67 void onRequest( void (*)(void) );
68
69 inline size_t write(unsigned long n) { return write((uint8_t)n); }
70 inline size_t write(long n) { return write((uint8_t)n); }
71 inline size_t write(unsigned int n) { return write((uint8_t)n); }
72 inline size_t write(int n) { return write((uint8_t)n); }
73 using Print::write;
74 };
75
76 extern TwoWire Wire;
77
78 #endif
79
@@ -0,0 +1,31
1 #######################################
2 # Syntax Coloring Map For Wire
3 #######################################
4
5 #######################################
6 # Datatypes (KEYWORD1)
7 #######################################
8
9 #######################################
10 # Methods and Functions (KEYWORD2)
11 #######################################
12
13 begin KEYWORD2
14 beginTransmission KEYWORD2
15 endTransmission KEYWORD2
16 requestFrom KEYWORD2
17 send KEYWORD2
18 receive KEYWORD2
19 onReceive KEYWORD2
20 onRequest KEYWORD2
21
22 #######################################
23 # Instances (KEYWORD2)
24 #######################################
25
26 Wire KEYWORD2
27
28 #######################################
29 # Constants (LITERAL1)
30 #######################################
31
@@ -0,0 +1,112
1 /*
2 * clock.cpp
3 *
4 * Created on: Nov 5, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include <clock.h>
9 #include <Wire/Wire.h>
10
11 namespace te_clock {
12
13 /*!
14 * \fn request
15 * \brief Escribe un valor en la memoria RAM interna del RTC DS1308, en la
16 * direccion especificada.
17 * \param addr direccion relativa a la RAM (0 es la primera) del registro
18 * en DS1308.
19 * \param reqcode El codigo del comando a ejecutar
20 */
21 inline uint8_t request(uint8_t reqcode, uint8_t addr=-1, uint8_t val=-1) {
22
23 Wire.beginTransmission(IDT5V19_CTRL_ID);
24 Wire.write(reqcode);
25 if(addr!=-1)Wire.write(addr);
26 if(val!=-1)Wire.write(val);
27 return Wire.endTransmission();
28 }
29
30 /*!
31 * \fn progsave
32 * \brief Escribe un valor en la memoria RAM interna del RTC DS1308, en la
33 * direccion especificada.
34 */
35 inline uint8_t progsave(void) {
36 return request(0x01);
37 }
38
39 /*!
40 * \fn progrestore
41 * \brief Escribe un valor en la memoria RAM interna del RTC DS1308, en la
42 * direccion especificada.
43 */
44 inline uint8_t progrestore(void) {
45 return request(0x02);
46 }
47
48 /*!
49 * \fn read
50 * \brief Lee un buffer de la memoria RAM interna del RTC DS1308, de la
51 * direccion especificada.
52 * \param addr direccion relativa a la RAM (0 es la primera) del registro
53 * en DS1308.
54 * \param buff Direccion del buffer al cual se copiaran los valores.
55 * \param cnt Numero de elementos acpiar del DS1308.
56 * \return estatus
57 * 0 success
58 * 2 error: address send, nack received
59 * 3 error: data send, nack received
60 * 4 other twi error
61 */
62 uint8_t progread(uint8_t addr, uint8_t buf[], uint8_t cnt ) {
63
64 uint8_t nread=0;
65 while( (cnt > 0) && ( addr < IDT5V19_MAX_ADD ) ) {
66 request(0x00, addr);
67 Wire.requestFrom((uint8_t)IDT5V19_CTRL_ID, cnt);
68 while(Wire.available() && (cnt > 0) && (addr < IDT5V19_MAX_ADD) ) {
69 buf[nread] = Wire.read();
70 nread++; cnt--; addr++;
71 } /* while */
72 }
73 return (nread);
74 }
75
76
77 /*!
78 * \fn progwrite
79 * \brief Escribe el contenido de un buffer de cnt elementos en la memoria
80 * RAM interna del RTC DS1308, en la direccion especificada.
81 * \param addr direccion relativa a la RAM (0 es la primera) del inicio del
82 * buffer en DS1308.
83 * \param pbuf direccion del buffer a copiar en la RAM del DS1308.
84 * \param cnt Numero de elementos a copiar.
85 * \return estatus
86 * 0 success
87 * 2 error: address send, nack received
88 * 3 error: data send, nack received
89 * 4 other twi error
90 */
91 uint8_t progwrite(uint8_t addr, const uint8_t *pbuf,uint8_t cnt) {
92
93 uint8_t nbytes, rc=0;
94 if (addr >= IDT5V19_MAX_ADD) return (IDT5V19_MAX_ADD); // 0 thru 55
95 if (addr+cnt > IDT5V19_MAX_ADD) cnt = IDT5V19_MAX_ADD-addr;
96 while (cnt > 0) {
97 nbytes = min(cnt, BUFFER_LENGTH-1);
98 Wire.beginTransmission(IDT5V19_CTRL_ID);
99 Wire.write(0x00);
100 Wire.write(addr);
101 Wire.write((uint8_t*)pbuf, nbytes);
102 rc = Wire.endTransmission();
103 cnt -=nbytes;
104 addr+=nbytes;
105 pbuf +=nbytes;
106 }
107 return(rc);
108 }
109
110
111
112 }
@@ -0,0 +1,36
1 /*
2 * clock.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef CLOCK_H_
9 #define CLOCK_H_
10
11 #include <Arduino.h>
12 #include <pins_arduino.h>
13 #include <Wire/Wire.h>
14 #include <Time/Time.h>
15 #include <te_structs.h>
16
17 namespace te_clock {
18
19 #define IDT5V19_CTRL_ID 0x6A
20
21 //pin ports to configure clock generator
22 #define SD_OE A10 /*!< PK2 AVR <> A10 Arduino */
23 #define SEL0 A11 /*!< PK3 AVR <> A11 Arduino */
24 #define SEL1 A12 /*!< PK4 AVR <> A12 Arduino */
25 #define SEL2 A13 /*!< PK5 AVR <> A13 Arduino */
26 #define CLKSEL A14 /*!< PK6 AVR <> A14 Arduino */
27
28 #define IDT5V19_MAX_ADD 0x37 /*!< Direccion del final de registros */
29
30 uint8_t read(uint8_t addr, uint8_t buf[], uint8_t cnt);
31 uint8_t write(uint8_t addr, uint8_t data);
32 uint8_t write(uint8_t addr, const uint8_t *pbuf,uint8_t cnt);
33
34 }
35
36 #endif /* CLOCK_H_ */
@@ -0,0 +1,21
1 /*
2 * gnss.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef GNSS_H_
9 #define GNSS_H_
10
11 namespace te_gnss {
12
13 //pin ports to GNSS
14 #define PPS 2 /*!< PE4 AVR <> 2 Arduino */
15 #define ENB 5 /*!< PE3 AVR <> 5 Arduino */
16 #define RX0_GNSS RX0
17 #define TX0_GNSS TX0 PE1
18
19 }
20
21 #endif /* GNSS_H_ */
@@ -0,0 +1,184
1 /*
2 * rtc1308.cpp
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #include <rtc1308.h>
9 #include <Wire/Wire.h>
10
11 namespace te_rtc{
12
13 /*!
14 * \fn initialization
15 * \brief Inicializacion del modulo que controlara al RTC DS1308.
16 */
17 void initialization(void) {
18
19 pinMode(CLKIN,OUTPUT);
20 attachInterrupt(PPS,ISR_gnss_pps, RISING);
21 }
22
23 /*!
24 * \fn configure
25 * \brief Configura el IC DS1308 para operacion con un PPS de GNSS como tick.
26 * \param rtc estructura que contien informacion de configuracion.
27 * \see rtc_config_struct
28 */
29 void configure(rtc_config_struct &rtc) {
30
31 uint8_t *ctl_byte = (uint8_t*)&rtc.ctl_byte;
32 uint8_t *clk_halt = (uint8_t*)&rtc.clk_halt;
33
34 Wire.beginTransmission(DS1308_CTRL_ID);
35 Wire.write(DS1308_CTL_ADD);
36 Wire.write(*clk_halt);
37 Wire.endTransmission();
38
39 Wire.beginTransmission(DS1308_CTRL_ID);
40 Wire.write(DS1308_CTL_ADD);
41 // CLKIN com 1Hz de entrada (1PPS)
42 Wire.write(*ctl_byte);
43 //Wire.write(1<<ECLK|0<<OSF|0<<LOS|0<<BBCLK|0<<RS1|0<<RS0);
44 Wire.endTransmission();
45 }
46
47 /*!
48 * \fn set_time
49 * \brief Setea el tiempo especificado en tm, en el IC DS1308.
50 * \param tm estructura que contien informacion de tiempo.
51 * \see tmElements_t
52 */
53 void set_time(tmElements_t &tm) {
54
55 Wire.beginTransmission(DS1308_CTRL_ID);
56 // start with Clock Control and the Seconds register
57 Wire.write(DS1308_SEC_ADD);
58 Wire.write((uint8_t)0x80); // Set clock control bit to 1. This stops the clock
59 Wire.write(dec2bcd(tm.Minute));
60 Wire.write(dec2bcd(tm.Hour)); // sets 24 hour format
61 Wire.write(dec2bcd(tm.Wday));
62 Wire.write(dec2bcd(tm.Day));
63 Wire.write(dec2bcd(tm.Month));
64 Wire.write(dec2bcd(tmYearToY2k(tm.Year)));
65 Wire.endTransmission();
66
67 Wire.beginTransmission(DS1308_CTRL_ID);
68 // Address the Clock Control and the Seconds register
69 Wire.write(DS1308_SEC_ADD);
70 // Set clock control bit to 0 and number of seconds. This starts the clock
71 Wire.write(dec2bcd(tm.Second));
72 Wire.endTransmission();
73 }
74
75 /*!
76 * \fn activate_pps
77 * \brief Activa la generacion de una senal de 1Hz (PPS) desde el RTC DS1308. Este
78 * PPS debe estar sincronizado con el PPS del GNSS.
79 */
80 void activate_pps(void) {
81 Wire.beginTransmission(DS1308_CTRL_ID);
82 Wire.write(DS1308_CTL_ADD);
83 // CLKIN com 1Hz de salida (1PPS)
84 Wire.write(0<<ECLK|0<<OSF|1<<SQWE|0<<LOS|0<<BBCLK|0<<RS1|0<<RS0);
85 Wire.endTransmission();
86 }
87
88 ///////////////////////////////////////////////////////////////////////////////
89
90
91 /*!
92 * \fn read_ram
93 * \brief Lee un buffer de la memoria RAM interna del RTC DS1308, de la
94 * direccion especificada.
95 * \param addr direccion relativa a la RAM (0 es la primera) del registro
96 * en DS1308.
97 * \param buff Direccion del buffer al cual se copiaran los valores.
98 * \param cnt Numero de elementos acpiar del DS1308.
99 * \return estatus
100 * 0 success
101 * 2 error: address send, nack received
102 * 3 error: data send, nack received
103 * 4 other twi error
104 */
105 uint8_t read_ram(uint8_t regaddr, uint8_t *pbuf, uint8_t cnt) {
106
107 uint8_t nread=0;
108 while( (cnt > 0) && ( regaddr < DS1308_RAM_REGS ) ) {
109 Wire.beginTransmission(DS1308_CTRL_ID);
110 Wire.write(regaddr+DS1308_RAM_BASE);
111 Wire.endTransmission();
112 Wire.requestFrom((uint8_t)DS1308_CTRL_ID, cnt);
113 while(Wire.available() && (cnt > 0) && (regaddr < DS1308_RAM_REGS) ) {
114 pbuf[nread] = Wire.read();
115 nread++; cnt--; regaddr++;
116 } /* while */
117 }
118 return (nread);
119 }
120
121 /*!
122 * \fn write_ram
123 * \brief Escribe un valor en la memoria RAM interna del RTC DS1308, en la
124 * direccion especificada.
125 * \param addr direccion relativa a la RAM (0 es la primera) del registro
126 * en DS1308.
127 * \param val valor que se desea escribir en el registro.
128 * \return estatus
129 * 0 success
130 * 2 error: address send, nack received
131 * 3 error: data send, nack received
132 * 4 other twi error
133 */
134 uint8_t write_ram(uint8_t regaddr, uint8_t val) {
135
136 uint8_t rc=0;
137 if (regaddr >= DS1308_RAM_REGS) return (DS1308_RAM_REGS); // 0 thru 51
138 Wire.beginTransmission(DS1308_CTRL_ID);
139 Wire.write(regaddr+DS1308_RAM_BASE);
140 Wire.write(val);
141 rc = Wire.endTransmission();
142 return(rc);
143 }
144
145 /*!
146 * \fn write_ram
147 * \brief Escribe el contenido de un buffer de cnt elementos en la memoria
148 * RAM interna del RTC DS1308, en la direccion especificada.
149 * \param addr direccion relativa a la RAM (0 es la primera) del inicio del
150 * buffer en DS1308.
151 * \param pbuf direccion del buffer a copiar en la RAM del DS1308.
152 * \param cnt Numero de elementos a copiar.
153 * \return estatus
154 * 0 success
155 * 2 error: address send, nack received
156 * 3 error: data send, nack received
157 * 4 other twi error
158 */
159 uint8_t write_ram(uint8_t regaddr, const uint8_t *pbuf,uint8_t cnt) {
160
161 uint8_t nbytes, rc=0;
162 if (regaddr >= DS1308_RAM_REGS) return (DS1308_RAM_REGS); // 0 thru 55
163 if (regaddr+cnt > DS1308_RAM_REGS) cnt = DS1308_RAM_REGS-regaddr;
164 while (cnt > 0) {
165 nbytes = min(cnt, BUFFER_LENGTH-1);
166 Wire.beginTransmission(DS1308_CTRL_ID);
167 Wire.write(regaddr+DS1308_RAM_BASE);
168 Wire.write((uint8_t*)pbuf, nbytes);
169 rc = Wire.endTransmission();
170 cnt -=nbytes;
171 regaddr+=nbytes;
172 pbuf +=nbytes;
173 }
174 return(rc);
175 }
176
177
178 // Convert Decimal to Binary Coded Decimal (BCD). 2 digits only
179 inline uint8_t dec2bcd(uint8_t val) {
180 return val + 6 * (val / 10);
181 }
182
183
184 }// end namespace rtc
@@ -0,0 +1,65
1 /*
2 * rtc1308.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef RTC1308_H_
9 #define RTC1308_H_
10
11 #include <Arduino.h>
12 #include <pins_arduino.h>
13 #include <Wire/Wire.h>
14 #include <Time/Time.h>
15 #include <te_structs.h>
16
17 extern void ISR_gnss_pps(void);
18
19 namespace te_rtc{
20
21 #define DS1308_CTRL_ID 0x68
22 #define DS1308_RAM_BASE 0x08 /*!< Direccion base de la memoria RAM */
23 #define DS1308_RAM_MAX 0x37 /*!< Direccion del final de la RAM */
24 #define DS1308_RAM_REGS (DS1308_RAM_MAX - DS1308_RAM_BASE + 1)
25
26 #define DS1308_SEC_ADD 0x00 /*!< Direccion de registro de configuracion de segundos */
27 #define DS1308_MIN_ADD 0x01 /*!< Direccion de registro de configuracion de minutos */
28 #define DS1308_HOU_ADD 0x02 /*!< Direccion de registro de configuracion de horas */
29 #define DS1308_DOW_ADD 0x03 /*!< Direccion de registro de configuracion de dia de la semana */
30 #define DS1308_DAT_ADD 0x04 /*!< Direccion de registro de configuracion de dia del mes */
31 #define DS1308_MON_ADD 0x05 /*!< Direccion de registro de configuracion de mes */
32 #define DS1308_YEA_ADD 0x06 /*!< Direccion de registro de configuracion de ahno */
33 #define DS1308_CTL_ADD 0x07 /*!< Direccion de registro de control */
34
35
36 #define OUT 7 /*!< Bit 7 en DS1308_CTL_ADD */
37 #define ECLK 6 /*!< Bit 6 en DS1308_CTL_ADD */
38 #define OSF 5 /*!< Bit 5 en DS1308_CTL_ADD */
39 #define SQWE 4 /*!< Bit 4 en DS1308_CTL_ADD */
40 #define LOS 3 /*!< Bit 3 en DS1308_CTL_ADD */
41 #define BBCLK 2 /*!< Bit 2 en DS1308_CTL_ADD */
42 #define RS1 1 /*!< Bit 1 en DS1308_CTL_ADD */
43 #define RS0 0 /*!< Bit 0 en DS1308_CTL_ADD */
44
45 //pin ports
46 #define CLKIN 38 /*!< internal PPS output PD7 AVR <> 38 ARDUINO MEGA */
47 #define PPS 0 /*|< GNSS receptor PPS signal interrupt int0, port 2 (Arduino i/o), pe4 (avr i/o) */
48
49
50 void initialization(void);
51 void configure(rtc_config_struct &rtc);
52 void set_time(tmElements_t &tm);
53 void activate_pps(void);
54
55 uint8_t read_ram(uint8_t regaddr, uint8_t *pbuf, uint8_t cnt);
56 uint8_t write_ram(uint8_t regaddr, uint8_t val);
57 uint8_t write_ram(uint8_t regaddr, const uint8_t *pbuf,uint8_t cnt);
58
59 inline uint8_t dec2bcd(uint8_t val);
60
61
62
63 }
64
65 #endif /* RTC1308_H_ */
@@ -0,0 +1,20
1 /*
2 * te2saig.h
3 *
4 * Created on: Nov 4, 2014
5 * Author: Alan Aguilar Sologuren
6 */
7
8 #ifndef TE2SAIG_H_
9 #define TE2SAIG_H_
10
11 // pin ports to Raspberry Pi
12 #define RX2_RBP RXD2
13 #define TX2_RBP TXD2
14
15 //pin ports to system
16 #define LOCK 42 /*!< GNSS receptor LOCK signal PL7 AVR <> 42 ARDUINO MEGA */
17
18
19
20 #endif /* TE2SAIG_H_ */
@@ -0,0 +1,1
1 link /home/aras/proyectos/gen_acq/trunk/firmware/sources/saigd/utils/te_structs.h No newline at end of file
@@ -0,0 +1,53
1 /*
2 main.cpp - Main loop for Arduino sketches
3 Copyright (c) 2005-2013 Arduino Team. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "rtc1308.h"
21 #include <Arduino.h>
22 #include <pins_arduino.h>
23 #include "te_structs.h"
24
25 //Declared weak in Arduino.h to allow user redefinitions.
26 int atexit(void (*func)()) { return 0; }
27
28
29 int main(void)
30 {
31 init();
32
33 setup();
34
35 for (;;) {
36 loop();
37 if (serialEventRun) serialEventRun();
38 }
39
40 return 0;
41 }
42
43 void setup(void){
44
45 }
46
47 void loop(void){
48
49 }
50
51 void ISR_gnss_pps(void) {
52
53 }
General Comments 0
You need to be logged in to leave comments. Login now