Pico-Arduino
PicoPinFunction.h
1 #pragma once
2 
3 #include "pico/stdlib.h"
4 #include "hardware/gpio.h"
5 #include "hardware/adc.h"
6 #include "hardware/gpio.h"
7 #include "hardware/adc.h"
8 #include "hardware/pwm.h"
9 #include "hardware/clocks.h"
10 
11 #ifndef PICO_MAX_PIN_COUNT
12 #define PICO_MAX_PIN_COUNT 40
13 #endif
14 
15 namespace pico_arduino {
16 
18 enum PinFunctionEnum {PIN_FUNC_UNDEFINED, PIN_FUNC_GPIO, PIN_FUNC_ADC, PIN_FUNC_PWM};
19 
20 // Forward declaraton
21 class PinSetup;
22 
28 struct PinInfo {
29  PinFunctionEnum pin_function;
30  PinMode pinMode;
31  bool is_setup = false;
32  bool is_defined = false;
33 };
34 
40 class PinSetup {
41 public:
42  virtual void setupPin(PinInfo *info, pin_size_t pin) = 0;
43  virtual bool usePin(PinInfo *info, pin_size_t pin) { return false; };
44 };
45 
51 class PinSetupADC : public PinSetup {
52 public:
53 
54  static PinSetupADC &instance() {
55  static PinSetupADC *ptr = new PinSetupADC();
56  return *ptr;
57  }
58 
59  virtual void setupPin(PinInfo *info, pin_size_t pinNumber) {
60  if (initADC()){
61  Logger.printf(PicoLogger::Debug, "PinSetupADC::setupPin %d\n", pinNumber);
62  }
63  }
64 
65  virtual bool usePin(PinInfo *info, pin_size_t pinNumber) {
66  Logger.printf(PicoLogger::Debug, "PinSetupADC::usePin %d\n", pinNumber);
67  int adc = pinNumber - 26;
68  return adcSelect(adc);
69  };
70 
71 
73  bool adcSelect(int adc){
74  bool changed = false;
75  if (current_adc != adc){
76  Logger.printf(PicoLogger::Debug, "adc_select_input %d\n",adc);
77  adc_select_input((id_t)adc);
78  current_adc = adc;
79  changed = true;
80  }
81  return changed;
82  }
83 
85  bool initADC(){
86  // init if necessary
87  bool result = false;
88  if (!adc_init_flag){
89  Logger.info("adc_init");
90  adc_init();
91  adc_init_flag = true;
92  result = true;
93  }
94  return result;
95  }
96 
97 protected:
98  bool adc_init_flag = false;
99  int current_adc;
100 
101  // singleton ! use the instance method to get the object
102  PinSetupADC() {
103  }
104 
105 };
106 
112 class PinSetupGPIO : public PinSetup {
113 public:
114  virtual void setupPin(PinInfo *info, pin_size_t pinNumber) {
115  Logger.debug("PinSetupGPIO::setupPin");
116  gpio_init(pinNumber);
117  gpio_set_dir(pinNumber, info->pinMode==OUTPUT ? GPIO_OUT: GPIO_IN);
118  if (info->pinMode==INPUT_PULLUP) gpio_pull_up(pinNumber);
119  if (info->pinMode==INPUT_PULLDOWN) gpio_pull_down(pinNumber);
120  info->is_setup = true;
121  }
122 };
123 
124 
134  public:
135  static PicoPinFunction &instance(){
136  static PicoPinFunction *inst_ptr;
137  if (inst_ptr==nullptr){
138  inst_ptr = new PicoPinFunction();
139  }
140  return *inst_ptr;
141  }
142 
144  bool setPinMode(pin_size_t pinNumber, PinMode pinMode){
145  Logger.debug("PicoGPIOFunction::PinMode");
146  bool changed = false;
147  if (!(pinInfo[pinNumber].is_defined) || pinInfo[pinNumber].pinMode != pinMode){
148  pinInfo[pinNumber].pinMode = pinMode;
149  pinInfo[pinNumber].is_setup = false;
150  pinInfo[pinNumber].is_defined = true;
151 
152  Logger.printf(PicoLogger::Debug, "PicoGPIOFunction::PinMode -> has changed - pin: %d\n", pinNumber);
153  changed = true;
154  }
155  return changed;
156  }
157 
159  bool isModeDefined(pin_size_t pinNumber) {
160  return pinInfo[pinNumber].is_defined;
161  }
162 
164  bool isInput(pin_size_t pinNumber){
165  return pinInfo[pinNumber].pinMode==INPUT;
166  }
167 
169  bool isOutput(pin_size_t pinNumber){
170  return pinInfo[pinNumber].pinMode==OUTPUT;
171  }
172 
174  bool isSetup(pin_size_t pinNumber){
175  return pinInfo[pinNumber].is_setup;
176  }
177 
179  void setSetup(pin_size_t pinNumber){
180  pinInfo[pinNumber].is_setup = true;
181  }
182 
184  PinMode pinMode(pin_size_t pinNumber) {
185  return (PinMode) pinInfo[pinNumber].pinMode;
186  }
187 
189  const char* pinModeStr(pin_size_t pinNumber){
190  if (isModeDefined(pinNumber)) {
191  return isInput(pinNumber) ? "INPUT" : "OUTPUT";
192  } else {
193  return "UNDEFINED";
194  }
195  }
196 
198  void clear(pin_size_t pinNumber){
199  Logger.debug("clear");
200  gpio_set_function(pinNumber, GPIO_FUNC_NULL);
201  pinInfo[pinNumber].is_setup = false;
202  }
203 
205  void usePin(pin_size_t pinNumber, PinFunctionEnum pinFunction, PinSetup *setup = nullptr){
206  Logger.printf(PicoLogger::Debug, "PicoGPIOFunction::usePin %d\n", pinNumber);
207  PinInfo *info = & (pinInfo[pinNumber]);
208  //Logger.debug("is_setup:", pinInfo[pinNumber].is_setup ? "true" : "false");
209  if (!info->is_setup) {
210  // initialize setup method
211  if (setup!=nullptr){
212  setup->setupPin(info, pinNumber);
213  info->is_setup = true;
214  }
215  }
216 
217  // fuctionality which needs to be executed each time before the pin use
218  if (setup!=nullptr){
219  setup->usePin(info, pinNumber);
220  }
221  }
222 
223  protected:
224  PinInfo* pinInfo;
225  bool adc_init_flag = false;
226  int current_adc;
227 
230  Logger.debug("PicoGPIOFunction");
231  pinInfo = new PinInfo[PICO_MAX_PIN_COUNT];
232  }
233 };
234 
235 }
236 
virtual int printf(LogLevel current_level, const char *fmt,...)
printf support
Definition: PicoLogger.h:65
virtual void info(const char *str, const char *str1=nullptr, const char *str2=nullptr)
logs an info message
Definition: PicoLogger.h:50
virtual void debug(const char *str, const char *str1=nullptr, const char *str2=nullptr)
writes an debug message
Definition: PicoLogger.h:60
The pico requires that the function of the pin is defined. In Arduino, there is no such concept - how...
Definition: PicoPinFunction.h:133
PinMode pinMode(pin_size_t pinNumber)
returns the pin mode
Definition: PicoPinFunction.h:184
void clear(pin_size_t pinNumber)
set gpio function to GPIO_FUNC_NULL
Definition: PicoPinFunction.h:198
bool isSetup(pin_size_t pinNumber)
checks if the setup has been done for the pin
Definition: PicoPinFunction.h:174
void usePin(pin_size_t pinNumber, PinFunctionEnum pinFunction, PinSetup *setup=nullptr)
setup Pico pin init function bysed on functionality
Definition: PicoPinFunction.h:205
bool isModeDefined(pin_size_t pinNumber)
checks if the mode was defined for the pin
Definition: PicoPinFunction.h:159
const char * pinModeStr(pin_size_t pinNumber)
returns the PinMode as string
Definition: PicoPinFunction.h:189
bool isInput(pin_size_t pinNumber)
checks if the pin has been defined as input
Definition: PicoPinFunction.h:164
bool setPinMode(pin_size_t pinNumber, PinMode pinMode)
defines the actual Arduino PinMode. Returns true if it needed to be changed
Definition: PicoPinFunction.h:144
bool isOutput(pin_size_t pinNumber)
checks if the pin has been defined as output
Definition: PicoPinFunction.h:169
void setSetup(pin_size_t pinNumber)
marks the pin setup as completed
Definition: PicoPinFunction.h:179
PicoPinFunction()
protected constructor because this is a singleton
Definition: PicoPinFunction.h:229
Pin Initialization for ADC.
Definition: PicoPinFunction.h:51
bool adcSelect(int adc)
select the ADC if it has been changed
Definition: PicoPinFunction.h:73
bool initADC()
calls adc_init() if necessary - returns true if it has been intialized (the first time)
Definition: PicoPinFunction.h:85
Pin Initialization for GPIO.
Definition: PicoPinFunction.h:112
Base class for function specific pin setup and pin use functionality.
Definition: PicoPinFunction.h:40
Pico Arduino Framework.
Definition: Arduino.cpp:26
PinFunctionEnum
Supported pin functions.
Definition: PicoPinFunction.h:18
Information about an the status and the Arduino PinMode of an individual pin.
Definition: PicoPinFunction.h:28