Raspberry Pi : BerryClip: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | # Raspberry Pi : BerryClip | |
| 2 | 2 | ||
| 3 | 3 |  | |
| 4 | 4 | ||
| 5 | 5 | The BerryClip 6 LED Board is a add-on board for the Raspberry Pi. It consists of a PCB populated with 6 coloured LEDs, one switch and one buzzer. It is easy to attach to the Pi’s GPIO header. | |
| 6 | 6 | ||
| 7 | 7 | ## Hardware | |
| 8 | 8 | ||
| 9 | 9 |  | |
| 10 | 10 | ||
| 11 | 11 | The following list shows the mapping between the components, the header pins and the GPIO references : | |
| 12 | 12 | ||
| 13 | 13 | - LED 1 - Pin 7 - GPIO4 | |
| 14 | 14 | - LED 2 - Pin 11 - GPIO17 | |
| 15 | 15 | - LED 3 - Pin 15 - GPIO22 | |
| 16 | 16 | - LED 4 - Pin 19 - GPIO10 | |
| 17 | 17 | - LED 5 - Pin 21 - GPIO9 | |
| 18 | 18 | - LED 6 - Pin 23 - GPIO11 | |
| 19 | 19 | - Buzzer - Pin 24 - GPIO8 | |
| 20 | 20 | - Switch - Pin 26 - GPIO7 | |
| 21 | 21 | ||
| 22 | 22 | | GPIO | Pin | | Pin | GPIO | | |
| 23 | 23 | |--------|-----|-----|-----|--------| | |
| 24 | 24 | | GPIO7 | 26 | | 25 | GND | | |
| 25 | 25 | | GPIO8 | 24 | | 23 | GPIO11 | | |
| 26 | 26 | | GPIO25 | 22 | | 21 | GPIO9 | | |
| 27 | 27 | | GND | 20 | | 19 | GPIO10 | | |
| 28 | 28 | | GPIO24 | 18 | | 17 | +3.3V | | |
| 29 | 29 | | GPIO23 | 16 | | 15 | GPIO22 | | |
| 30 | 30 | | GND | 14 | | 13 | GPIO27 | | |
| 31 | 31 | | GPIO18 | 12 | | 11 | GPIO17 | | |
| 32 | 32 | | GPIO15 | 10 | | 9 | GND | | |
| 33 | 33 | | GPIO14 | 8 | | 7 | GPIO4 | | |
| 34 | 34 | | GND | 6 | | 5 | GPIO3 | | |
| 35 | 35 | | +5V | 4 | | 3 | GPIO2 | | |
| 36 | 36 | | +5V | 2 | | 1 | +3.3V | | |
| 37 | 37 | ||
| 38 | 38 | ## Software | |
| 39 | 39 | ||
| 40 | 40 |  | |
| 41 | 41 | ||
| 42 | 42 | The following example lists a program that controls berryClip. | |
| 43 | 43 | ||
| 44 | 44 | The code requires to be run as root (eg. sudo ./berryclipdemo). | |
| 45 | 45 | ||
| 46 | 46 | | Level | | Unit | | |
| 47 | 47 | |----|----|----| | |
| 48 | 48 | | 1 | User interface, Application level | unit1.pas, unit1.lfm, berryclipdemo.lpr | | |
| 49 | 49 | | 2 | Board level | uberryclip.pas | | |
| 50 | 50 | | 3 | | uraspberrypi.pas | | |
| 51 | 51 | | 4 | I/O driver | pi_io_unit.pas | | |
| 52 | 52 | ||
| 53 | 53 | ### User interface | |
| 54 | 54 | ||
| 55 | 55 |  | |
| 56 | 56 | ||
| 57 | 57 | The user interface consists of the buttons that control the LEDs and buzzer. In addition, the switch status is displayed on LED. LEDs state on the circuit board is displayed with the LEDs on the form. The berryclipdemo program uses the following components: [[TApplicationProperties]], [[TButton]], [[TShape]] and [[TToggleBox]]. | |
| 58 | 58 | ||
| 59 | 59 | #### unit1.pas | |
| 60 | 60 | ||
| 61 | 61 | ``` pascal | |
| 62 | 62 | unit Unit1; | |
| 63 | 63 | ||
| 64 | 64 | {$mode objfpc}{$H+} | |
| 65 | 65 | ||
| 66 | 66 | interface | |
| 67 | 67 | ||
| 68 | 68 | uses | |
| 69 | 69 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, | |
| 70 | 70 | ExtCtrls, uberryclip; | |
| 71 | 71 | ||
| 72 | 72 | type | |
| 73 | 73 | ||
| 74 | 74 | { TForm1 } | |
| 75 | 75 | ||
| 76 | 76 | TForm1 = class(TForm) | |
| 77 | 77 | ApplicationProperties1: TApplicationProperties; | |
| 78 | 78 | Button1: TButton; | |
| 79 | 79 | Led4ToggleBox: TToggleBox; | |
| 80 | 80 | Led6ToggleBox: TToggleBox; | |
| 81 | 81 | Led2ToggleBox: TToggleBox; | |
| 82 | 82 | Led3ToggleBox: TToggleBox; | |
| 83 | 83 | Led1ToggleBox: TToggleBox; | |
| 84 | 84 | Led5ToggleBox: TToggleBox; | |
| 85 | 85 | Shape1: TShape; | |
| 86 | 86 | Shape2: TShape; | |
| 87 | 87 | Shape3: TShape; | |
| 88 | 88 | Shape4: TShape; | |
| 89 | 89 | Shape5: TShape; | |
| 90 | 90 | Shape6: TShape; | |
| 91 | 91 | Shape7: TShape; | |
| 92 | 92 | procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean); | |
| 93 | 93 | procedure Button1MouseDown(Sender: TObject; Button: TMouseButton; | |
| 94 | 94 | Shift: TShiftState; X, Y: Integer); | |
| 95 | 95 | procedure Button1MouseUp(Sender: TObject; Button: TMouseButton; | |
| 96 | 96 | Shift: TShiftState; X, Y: Integer); | |
| 97 | 97 | procedure FormCreate(Sender: TObject); | |
| 98 | 98 | procedure FormDestroy(Sender: TObject); | |
| 99 | 99 | procedure Led1ToggleBoxChange(Sender: TObject); | |
| 100 | 100 | procedure Led2ToggleBoxChange(Sender: TObject); | |
| 101 | 101 | procedure Led3ToggleBoxChange(Sender: TObject); | |
| 102 | 102 | procedure Led4ToggleBoxChange(Sender: TObject); | |
| 103 | 103 | procedure Led5ToggleBoxChange(Sender: TObject); | |
| 104 | 104 | procedure Led6ToggleBoxChange(Sender: TObject); | |
| 105 | 105 | private | |
| 106 | 106 | { private declarations } | |
| 107 | 107 | Berry_Clip:TBerryClip; | |
| 108 | 108 | public | |
| 109 | 109 | { public declarations } | |
| 110 | 110 | end; | |
| 111 | 111 | ||
| 112 | 112 | var | |
| 113 | 113 | Form1: TForm1; | |
| 114 | 114 | ||
| 115 | 115 | implementation | |
| 116 | 116 | ||
| 117 | 117 | {$R *.lfm} | |
| 118 | 118 | ||
| 119 | 119 | { TForm1 } | |
| 120 | 120 | ||
| 121 | 121 | procedure TForm1.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean); | |
| 122 | 122 | begin | |
| 123 | 123 | if Berry_Clip.ReadSwitch | |
| 124 | 124 | then shape7.Brush.Color:=clBlack | |
| 125 | 125 | else shape7.Brush.Color:=clWhite; | |
| 126 | 126 | end; | |
| 127 | 127 | ||
| 128 | 128 | procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; | |
| 129 | 129 | Shift: TShiftState; X, Y: Integer); | |
| 130 | 130 | begin | |
| 131 | 131 | Berry_Clip.SetBuzzerOn; | |
| 132 | 132 | end; | |
| 133 | 133 | ||
| 134 | 134 | procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton; | |
| 135 | 135 | Shift: TShiftState; X, Y: Integer); | |
| 136 | 136 | begin | |
| 137 | 137 | Berry_Clip.SetBuzzerOff; | |
| 138 | 138 | end; | |
| 139 | 139 | ||
| 140 | 140 | procedure TForm1.FormCreate(Sender: TObject); | |
| 141 | 141 | begin | |
| 142 | 142 | Berry_Clip := TBerryClip.Create; | |
| 143 | 143 | end; | |
| 144 | 144 | ||
| 145 | 145 | procedure TForm1.FormDestroy(Sender: TObject); | |
| 146 | 146 | begin | |
| 147 | 147 | Berry_Clip.Free; | |
| 148 | 148 | end; | |
| 149 | 149 | ||
| 150 | 150 | procedure TForm1.Led1ToggleBoxChange(Sender: TObject); | |
| 151 | 151 | begin | |
| 152 | 152 | if Led1ToggleBox.Checked then | |
| 153 | 153 | begin | |
| 154 | 154 | Berry_Clip.SetLedOn(1); | |
| 155 | 155 | shape1.Brush.Color:=clRed ; | |
| 156 | 156 | end | |
| 157 | 157 | else | |
| 158 | 158 | begin | |
| 159 | 159 | Berry_Clip.SetLedOff(1); | |
| 160 | 160 | shape1.Brush.Color:=clWhite; | |
| 161 | 161 | end; | |
| 162 | 162 | end; | |
| 163 | 163 | ||
| 164 | 164 | procedure TForm1.Led2ToggleBoxChange(Sender: TObject); | |
| 165 | 165 | begin | |
| 166 | 166 | if Led2ToggleBox.Checked then | |
| 167 | 167 | begin | |
| 168 | 168 | Berry_Clip.SetLedOn(2); | |
| 169 | 169 | shape2.Brush.Color:=clRed; | |
| 170 | 170 | end | |
| 171 | 171 | else | |
| 172 | 172 | begin | |
| 173 | 173 | Berry_Clip.SetLedOff(2); | |
| 174 | 174 | shape2.Brush.Color:=clWhite; | |
| 175 | 175 | end; | |
| 176 | 176 | end; | |
| 177 | 177 | ||
| 178 | 178 | procedure TForm1.Led3ToggleBoxChange(Sender: TObject); | |
| 179 | 179 | begin | |
| 180 | 180 | if Led3ToggleBox.Checked then | |
| 181 | 181 | begin | |
| 182 | 182 | Berry_Clip.SetLedOn(3); | |
| 183 | 183 | shape3.Brush.Color:=clYellow; | |
| 184 | 184 | end | |
| 185 | 185 | else | |
| 186 | 186 | begin | |
| 187 | 187 | Berry_Clip.SetLedOff(3); | |
| 188 | 188 | shape3.Brush.Color:=clWhite; | |
| 189 | 189 | end; | |
| 190 | 190 | end; | |
| 191 | 191 | ||
| 192 | 192 | procedure TForm1.Led4ToggleBoxChange(Sender: TObject); | |
| 193 | 193 | begin | |
| 194 | 194 | if Led4ToggleBox.Checked then | |
| 195 | 195 | begin | |
| 196 | 196 | Berry_Clip.SetLedOn(4); | |
| 197 | 197 | shape4.Brush.Color:=clYellow; | |
| 198 | 198 | end | |
| 199 | 199 | else | |
| 200 | 200 | begin | |
| 201 | 201 | Berry_Clip.SetLedOff(4); | |
| 202 | 202 | shape4.Brush.Color:=clWhite; | |
| 203 | 203 | end; | |
| 204 | 204 | end; | |
| 205 | 205 | ||
| 206 | 206 | procedure TForm1.Led5ToggleBoxChange(Sender: TObject); | |
| 207 | 207 | begin | |
| 208 | 208 | if Led5ToggleBox.Checked then | |
| 209 | 209 | begin | |
| 210 | 210 | Berry_Clip.SetLedOn(5); | |
| 211 | 211 | shape5.Brush.Color:=clGreen; | |
| 212 | 212 | end | |
| 213 | 213 | else | |
| 214 | 214 | begin | |
| 215 | 215 | Berry_Clip.SetLedOff(5); | |
| 216 | 216 | shape5.Brush.Color:=clWhite; | |
| 217 | 217 | end; | |
| 218 | 218 | end; | |
| 219 | 219 | ||
| 220 | 220 | procedure TForm1.Led6ToggleBoxChange(Sender: TObject); | |
| 221 | 221 | begin | |
| 222 | 222 | if Led6ToggleBox.Checked then | |
| 223 | 223 | begin | |
| 224 | 224 | Berry_Clip.SetLedOn(6); | |
| 225 | 225 | shape6.Brush.Color:=clGreen; | |
| 226 | 226 | end | |
| 227 | 227 | else | |
| 228 | 228 | begin | |
| 229 | 229 | Berry_Clip.SetLedOff(6); | |
| 230 | 230 | shape6.Brush.Color:=clWhite; | |
| 231 | 231 | end; | |
| 232 | 232 | end; | |
| 233 | 233 | ||
| 234 | 234 | end. | |
| 235 | 235 | ``` | |
| 236 | 236 | ||
| 237 | 237 | #### unit1.lfm | |
| 238 | 238 | ||
| 239 | - | ||
| 239 | + | ``` lfm | |
| 240 | 240 | object Form1: TForm1 | |
| 241 | 241 | Left = 269 | |
| 242 | 242 | Height = 184 | |
| 243 | 243 | Top = 175 | |
| 244 | 244 | Width = 176 | |
| 245 | 245 | Caption = 'BerryClip' | |
| 246 | 246 | ClientHeight = 184 | |
| 247 | 247 | ClientWidth = 176 | |
| 248 | 248 | OnCreate = FormCreate | |
| 249 | 249 | OnDestroy = FormDestroy | |
| 250 | 250 | object Led2ToggleBox: TToggleBox | |
| 251 | 251 | Left = 8 | |
| 252 | 252 | Height = 24 | |
| 253 | 253 | Top = 32 | |
| 254 | 254 | Width = 128 | |
| 255 | 255 | Caption = 'Led2ToggleBox' | |
| 256 | 256 | OnChange = Led2ToggleBoxChange | |
| 257 | 257 | TabOrder = 0 | |
| 258 | 258 | end | |
| 259 | 259 | object Led1ToggleBox: TToggleBox | |
| 260 | 260 | Left = 8 | |
| 261 | 261 | Height = 24 | |
| 262 | 262 | Top = 8 | |
| 263 | 263 | Width = 128 | |
| 264 | 264 | Caption = 'Led1ToggleBox' | |
| 265 | 265 | OnChange = Led1ToggleBoxChange | |
| 266 | 266 | TabOrder = 1 | |
| 267 | 267 | end | |
| 268 | 268 | object Led3ToggleBox: TToggleBox | |
| 269 | 269 | Left = 8 | |
| 270 | 270 | Height = 24 | |
| 271 | 271 | Top = 56 | |
| 272 | 272 | Width = 128 | |
| 273 | 273 | Caption = 'Led3ToggleBox' | |
| 274 | 274 | OnChange = Led3ToggleBoxChange | |
| 275 | 275 | TabOrder = 2 | |
| 276 | 276 | end | |
| 277 | 277 | object Led4ToggleBox: TToggleBox | |
| 278 | 278 | Left = 8 | |
| 279 | 279 | Height = 24 | |
| 280 | 280 | Top = 80 | |
| 281 | 281 | Width = 128 | |
| 282 | 282 | Caption = 'Led4ToggleBox' | |
| 283 | 283 | OnChange = Led4ToggleBoxChange | |
| 284 | 284 | TabOrder = 3 | |
| 285 | 285 | end | |
| 286 | 286 | object Led5ToggleBox: TToggleBox | |
| 287 | 287 | Left = 8 | |
| 288 | 288 | Height = 24 | |
| 289 | 289 | Top = 104 | |
| 290 | 290 | Width = 128 | |
| 291 | 291 | Caption = 'Led5ToggleBox' | |
| 292 | 292 | OnChange = Led5ToggleBoxChange | |
| 293 | 293 | TabOrder = 4 | |
| 294 | 294 | end | |
| 295 | 295 | object Led6ToggleBox: TToggleBox | |
| 296 | 296 | Left = 8 | |
| 297 | 297 | Height = 24 | |
| 298 | 298 | Top = 128 | |
| 299 | 299 | Width = 128 | |
| 300 | 300 | Caption = 'Led6ToggleBox' | |
| 301 | 301 | OnChange = Led6ToggleBoxChange | |
| 302 | 302 | TabOrder = 5 | |
| 303 | 303 | end | |
| 304 | 304 | object Shape1: TShape | |
| 305 | 305 | Left = 144 | |
| 306 | 306 | Height = 18 | |
| 307 | 307 | Top = 12 | |
| 308 | 308 | Width = 16 | |
| 309 | 309 | Shape = stCircle | |
| 310 | 310 | end | |
| 311 | 311 | object Shape2: TShape | |
| 312 | 312 | Left = 144 | |
| 313 | 313 | Height = 18 | |
| 314 | 314 | Top = 34 | |
| 315 | 315 | Width = 16 | |
| 316 | 316 | Shape = stCircle | |
| 317 | 317 | end | |
| 318 | 318 | object Shape3: TShape | |
| 319 | 319 | Left = 144 | |
| 320 | 320 | Height = 18 | |
| 321 | 321 | Top = 58 | |
| 322 | 322 | Width = 16 | |
| 323 | 323 | Shape = stCircle | |
| 324 | 324 | end | |
| 325 | 325 | object Shape4: TShape | |
| 326 | 326 | Left = 144 | |
| 327 | 327 | Height = 18 | |
| 328 | 328 | Top = 82 | |
| 329 | 329 | Width = 16 | |
| 330 | 330 | Shape = stCircle | |
| 331 | 331 | end | |
| 332 | 332 | object Shape5: TShape | |
| 333 | 333 | Left = 144 | |
| 334 | 334 | Height = 18 | |
| 335 | 335 | Top = 106 | |
| 336 | 336 | Width = 16 | |
| 337 | 337 | Shape = stCircle | |
| 338 | 338 | end | |
| 339 | 339 | object Shape6: TShape | |
| 340 | 340 | Left = 144 | |
| 341 | 341 | Height = 18 | |
| 342 | 342 | Top = 130 | |
| 343 | 343 | Width = 16 | |
| 344 | 344 | Shape = stCircle | |
| 345 | 345 | end | |
| 346 | 346 | object Shape7: TShape | |
| 347 | 347 | Left = 144 | |
| 348 | 348 | Height = 18 | |
| 349 | 349 | Top = 158 | |
| 350 | 350 | Width = 16 | |
| 351 | 351 | Shape = stCircle | |
| 352 | 352 | end | |
| 353 | 353 | object Button1: TButton | |
| 354 | 354 | Left = 8 | |
| 355 | 355 | Height = 25 | |
| 356 | 356 | Top = 151 | |
| 357 | 357 | Width = 64 | |
| 358 | 358 | Caption = 'Buzzer' | |
| 359 | 359 | OnMouseDown = Button1MouseDown | |
| 360 | 360 | OnMouseUp = Button1MouseUp | |
| 361 | 361 | TabOrder = 6 | |
| 362 | 362 | end | |
| 363 | 363 | object ApplicationProperties1: TApplicationProperties | |
| 364 | 364 | OnIdle = ApplicationProperties1Idle | |
| 365 | 365 | left = 72 | |
| 366 | 366 | top = 152 | |
| 367 | 367 | end | |
| 368 | 368 | end | |
| 369 | 369 | ``` | |
| 370 | 370 | ||
| 371 | 371 | ### Main | |
| 372 | 372 | ||
| 373 | 373 | ``` pascal | |
| 374 | 374 | program berryclipdemo; | |
| 375 | 375 | ||
| 376 | 376 | {$mode objfpc}{$H+} | |
| 377 | 377 | ||
| 378 | 378 | uses | |
| 379 | 379 | {$IFDEF UNIX}{$IFDEF UseCThreads} | |
| 380 | 380 | cthreads, | |
| 381 | 381 | {$ENDIF}{$ENDIF} | |
| 382 | 382 | Interfaces, // this includes the LCL widgetset | |
| 383 | 383 | Forms, Unit1, pi_io_unit, uberryclip, uraspberrypi | |
| 384 | 384 | { you can add units after this }; | |
| 385 | 385 | ||
| 386 | 386 | {$R *.res} | |
| 387 | 387 | ||
| 388 | 388 | begin | |
| 389 | 389 | RequireDerivedFormResource := True; | |
| 390 | 390 | Application.Initialize; | |
| 391 | 391 | Application.CreateForm(TForm1, Form1); | |
| 392 | 392 | Application.Run; | |
| 393 | 393 | end. | |
| 394 | 394 | ``` | |
| 395 | 395 | ||
| 396 | 396 | ### Board | |
| 397 | 397 | ||
| 398 | 398 | #### uberryclip.pas | |
| 399 | 399 | ||
| 400 | 400 | ``` pascal | |
| 401 | 401 | unit uberryclip; | |
| 402 | 402 | ||
| 403 | 403 | {$mode objfpc}{$H+} | |
| 404 | 404 | ||
| 405 | 405 | interface | |
| 406 | 406 | ||
| 407 | 407 | uses | |
| 408 | 408 | Classes, SysUtils, | |
| 409 | 409 | uRaspberrypi; | |
| 410 | 410 | type | |
| 411 | 411 | ||
| 412 | 412 | { TBerryClip } | |
| 413 | 413 | ||
| 414 | 414 | TBerryClip = class | |
| 415 | 415 | private | |
| 416 | 416 | RaspBerryPi : TRaspBerryPi; | |
| 417 | 417 | public | |
| 418 | 418 | constructor Create; | |
| 419 | 419 | procedure SetLedOn( led_no :integer ); | |
| 420 | 420 | procedure SetLedOff( led_no :integer ); | |
| 421 | 421 | procedure SetBuzzerOn; | |
| 422 | 422 | procedure SetBuzzerOff; | |
| 423 | 423 | function ReadSwitch:boolean; | |
| 424 | 424 | destructor Destroy; override; | |
| 425 | 425 | end; | |
| 426 | 426 | implementation | |
| 427 | 427 | ||
| 428 | 428 | { TBerryClip } | |
| 429 | 429 | ||
| 430 | 430 | constructor TBerryClip.Create; | |
| 431 | 431 | begin | |
| 432 | 432 | RaspBerryPi := TRaspBerryPi.Create; | |
| 433 | 433 | RaspBerryPi.SetGpioPinOutput(GPIO4); // Led 1 | |
| 434 | 434 | RaspBerryPi.SetGpioPinOutput(GPIO9); // Led 2 | |
| 435 | 435 | RaspBerryPi.SetGpioPinOutput(GPIO10);// Led 3 | |
| 436 | 436 | RaspBerryPi.SetGpioPinOutput(GPIO11);// Led 4 | |
| 437 | 437 | RaspBerryPi.SetGpioPinOutput(GPIO17);// Led 5 | |
| 438 | 438 | RaspBerryPi.SetGpioPinOutput(GPIO22);// Led 6 | |
| 439 | 439 | RaspBerryPi.SetGpioPinInput(GPIO7); // Switch | |
| 440 | 440 | RaspBerryPi.SetGpioPinOutput(GPIO8); // Buzzer | |
| 441 | 441 | end; | |
| 442 | 442 | ||
| 443 | 443 | procedure TBerryClip.SetLedOn(led_no: integer); | |
| 444 | 444 | begin | |
| 445 | 445 | case led_no of | |
| 446 | 446 | 1 : RaspBerryPi.SetGpioBit(GPIO4); | |
| 447 | 447 | 2 : RaspBerryPi.SetGpioBit(GPIO17); | |
| 448 | 448 | 3 : RaspBerryPi.SetGpioBit(GPIO22); | |
| 449 | 449 | 4 : RaspBerryPi.SetGpioBit(GPIO10); | |
| 450 | 450 | 5 : RaspBerryPi.SetGpioBit(GPIO9); | |
| 451 | 451 | 6 : RaspBerryPi.SetGpioBit(GPIO11); | |
| 452 | 452 | end; | |
| 453 | 453 | end; | |
| 454 | 454 | ||
| 455 | 455 | procedure TBerryClip.SetLedOff(led_no: integer); | |
| 456 | 456 | begin | |
| 457 | 457 | case led_no of | |
| 458 | 458 | 1 : RaspBerryPi.ClearGpioBit(GPIO4); | |
| 459 | 459 | 2 : RaspBerryPi.ClearGpioBit(GPIO17); | |
| 460 | 460 | 3 : RaspBerryPi.ClearGpioBit(GPIO22); | |
| 461 | 461 | 4 : RaspBerryPi.ClearGpioBit(GPIO10); | |
| 462 | 462 | 5 : RaspBerryPi.ClearGpioBit(GPIO9); | |
| 463 | 463 | 6 : RaspBerryPi.ClearGpioBit(GPIO11); | |
| 464 | 464 | end; | |
| 465 | 465 | ||
| 466 | 466 | end; | |
| 467 | 467 | ||
| 468 | 468 | procedure TBerryClip.SetBuzzerOn; | |
| 469 | 469 | begin | |
| 470 | 470 | RaspBerryPi.SetGpioBit(GPIO8); | |
| 471 | 471 | end; | |
| 472 | 472 | ||
| 473 | 473 | procedure TBerryClip.SetBuzzerOff; | |
| 474 | 474 | begin | |
| 475 | 475 | RaspBerryPi.ClearGpioBit(GPIO8); | |
| 476 | 476 | end; | |
| 477 | 477 | ||
| 478 | 478 | function TBerryClip.ReadSwitch: boolean; | |
| 479 | 479 | begin | |
| 480 | 480 | result := RaspBerryPi.GetGpioBit(GPIO7); | |
| 481 | 481 | end; | |
| 482 | 482 | ||
| 483 | 483 | destructor TBerryClip.Destroy; | |
| 484 | 484 | begin | |
| 485 | 485 | RaspBerryPi.Free; | |
| 486 | 486 | inherited Destroy; | |
| 487 | 487 | end; | |
| 488 | 488 | ||
| 489 | 489 | end. | |
| 490 | 490 | ``` | |
| 491 | 491 | ||
| 492 | 492 | #### uraspberrypi.pas | |
| 493 | 493 | ||
| 494 | 494 | ``` pascal | |
| 495 | 495 | unit uraspberrypi; | |
| 496 | 496 | ||
| 497 | 497 | {$mode objfpc}{$H+} | |
| 498 | 498 | ||
| 499 | 499 | interface | |
| 500 | 500 | ||
| 501 | 501 | uses | |
| 502 | 502 | Classes, SysUtils, pi_io_unit, dialogs; | |
| 503 | 503 | ||
| 504 | 504 | const | |
| 505 | 505 | ||
| 506 | 506 | GPIO4 = 4; | |
| 507 | 507 | GPIO7 = 7; | |
| 508 | 508 | GPIO8 = 8; | |
| 509 | 509 | GPIO9 = 9; | |
| 510 | 510 | GPIO10= 10; | |
| 511 | 511 | GPIO11= 11; | |
| 512 | 512 | GPIO17= 17; | |
| 513 | 513 | GPIO22= 22; | |
| 514 | 514 | ||
| 515 | 515 | type | |
| 516 | 516 | ||
| 517 | 517 | { TRaspBerryPi } | |
| 518 | 518 | ||
| 519 | 519 | TRaspBerryPi = class | |
| 520 | 520 | private | |
| 521 | 521 | io_port: T_IO_Port; | |
| 522 | 522 | public | |
| 523 | 523 | constructor Create; | |
| 524 | 524 | procedure ClearGpioBit(no:byte); | |
| 525 | 525 | function GetGpioBit(no:byte):boolean; | |
| 526 | 526 | procedure SetGpioBit(no:byte); | |
| 527 | 527 | procedure SetGpioPinInput( no:byte); | |
| 528 | 528 | procedure SetGpioPinOutput( no:byte); | |
| 529 | 529 | destructor Destroy; override; | |
| 530 | 530 | end; | |
| 531 | 531 | ||
| 532 | 532 | implementation | |
| 533 | 533 | ||
| 534 | 534 | { TRaspBerryPi } | |
| 535 | 535 | ||
| 536 | 536 | constructor TRaspBerryPi.Create; | |
| 537 | 537 | begin | |
| 538 | 538 | if not MapIo | |
| 539 | 539 | then ShowMessage('Error mapping gpio') | |
| 540 | 540 | else | |
| 541 | 541 | begin | |
| 542 | 542 | io_port := T_IO_Port.Create; | |
| 543 | 543 | io_port.f_gpio := CreatePort(GPIO_BASE); | |
| 544 | 544 | end ; | |
| 545 | 545 | end; | |
| 546 | 546 | ||
| 547 | 547 | procedure TRaspBerryPi.ClearGpioBit(no: byte); | |
| 548 | 548 | begin | |
| 549 | 549 | io_port.ClearBit(no); | |
| 550 | 550 | end; | |
| 551 | 551 | ||
| 552 | 552 | function TRaspBerryPi.GetGpioBit(no: byte): boolean; | |
| 553 | 553 | begin | |
| 554 | 554 | result := io_port.GetBit(no); | |
| 555 | 555 | end; | |
| 556 | 556 | ||
| 557 | 557 | procedure TRaspBerryPi.SetGpioBit(no: byte); | |
| 558 | 558 | begin | |
| 559 | 559 | io_port.SetBit(no); | |
| 560 | 560 | end; | |
| 561 | 561 | ||
| 562 | 562 | procedure TRaspBerryPi.SetGpioPinInput(no: byte); | |
| 563 | 563 | begin | |
| 564 | 564 | io_port.SetPinMode(no,INPUT); | |
| 565 | 565 | end; | |
| 566 | 566 | ||
| 567 | 567 | procedure TRaspBerryPi.SetGpioPinOutput(no: byte); | |
| 568 | 568 | begin | |
| 569 | 569 | io_port.SetPinMode(no,OUTPUT); | |
| 570 | 570 | end; | |
| 571 | 571 | ||
| 572 | 572 | destructor TRaspBerryPi.Destroy; | |
| 573 | 573 | begin | |
| 574 | 574 | io_port.ClearBit(GPIO4); | |
| 575 | 575 | io_port.ClearBit(GPIO9); | |
| 576 | 576 | io_port.ClearBit(GPIO10); | |
| 577 | 577 | io_port.ClearBit(GPIO11); | |
| 578 | 578 | io_port.ClearBit(GPIO17); | |
| 579 | 579 | io_port.ClearBit(GPIO22); | |
| 580 | 580 | io_port.ClearBit(GPIO8); | |
| 581 | 581 | UnMapIo(io_port); | |
| 582 | 582 | io_port.free; | |
| 583 | 583 | inherited Destroy; | |
| 584 | 584 | end; | |
| 585 | 585 | ||
| 586 | 586 | end. | |
| 587 | 587 | ``` | |
| 588 | 588 | ||
| 589 | 589 | #### pi_io_unit.pas | |
| 590 | 590 | ||
| 591 | 591 | ``` pascal | |
| 592 | 592 | unit pi_io_unit; | |
| 593 | 593 | // This code is tested only RPI2B Processor | |
| 594 | 594 | {$mode objfpc}{$H+} | |
| 595 | 595 | ||
| 596 | 596 | interface | |
| 597 | 597 | ||
| 598 | 598 | uses | |
| 599 | 599 | Classes, SysUtils, Unix, BaseUnix; | |
| 600 | 600 | ||
| 601 | 601 | const | |
| 602 | 602 | BCM2709_PBASE= $3F000000; // Peripheral Base in Bytes (RPI2B Processor) | |
| 603 | 603 | // BCM2708_PBASE= $20000000; // Peripheral Base (maybe RPI1 ) | |
| 604 | 604 | REG_GPIO = BCM2709_PBASE div $1000; // $3F000 ; | |
| 605 | 605 | PAGE_SIZE = $1000; | |
| 606 | 606 | ||
| 607 | 607 | GPIO_BASE = (REG_GPIO + $200); | |
| 608 | 608 | ||
| 609 | 609 | INPUT = 0; | |
| 610 | 610 | OUTPUT = 1; | |
| 611 | 611 | ||
| 612 | 612 | GPSET = $1C; // GPIO Pin Output Set | |
| 613 | 613 | GPCLR = $28; // GPIO Pin Output Clear | |
| 614 | 614 | GPLEV = $34; // GPIO Pin Level | |
| 615 | 615 | ||
| 616 | 616 | type | |
| 617 | 617 | ||
| 618 | 618 | { T_IO_Port } | |
| 619 | 619 | ||
| 620 | 620 | T_IO_Port = class | |
| 621 | 621 | private | |
| 622 | 622 | public | |
| 623 | 623 | f_gpio: PLongWord; | |
| 624 | 624 | procedure SetPinMode(a_io_pin, a_mode: byte); | |
| 625 | 625 | function GetBit(a_io_pin : byte):boolean;inline; | |
| 626 | 626 | procedure ClearBit(a_io_pin : byte);inline; | |
| 627 | 627 | procedure SetBit(a_io_pin : byte);inline; | |
| 628 | 628 | end; | |
| 629 | 629 | ||
| 630 | 630 | function MapIo:boolean;// creates io mapping | |
| 631 | 631 | procedure UnMapIo(a_Map: T_IO_Port);// close io | |
| 632 | 632 | function CreatePort(PortGpio: LongWord): PLongWord; | |
| 633 | 633 | ||
| 634 | 634 | implementation | |
| 635 | 635 | ||
| 636 | 636 | var | |
| 637 | 637 | fd: integer;// /dev/mem file handle | |
| 638 | 638 | ||
| 639 | 639 | function MapIo: boolean; | |
| 640 | 640 | begin | |
| 641 | 641 | result := true; | |
| 642 | 642 | fd := fpopen('/dev/mem', O_RdWr or O_Sync); | |
| 643 | 643 | if fd < 0 then result := false; // unsuccessful mapping | |
| 644 | 644 | end; | |
| 645 | 645 | ||
| 646 | 646 | procedure UnMapIo( a_Map: T_IO_Port); | |
| 647 | 647 | begin | |
| 648 | 648 | if a_Map.f_gpio <> nil then | |
| 649 | 649 | begin | |
| 650 | 650 | fpMUnmap(a_Map.f_gpio, PAGE_SIZE); | |
| 651 | 651 | a_Map.f_gpio := nil; | |
| 652 | 652 | end; | |
| 653 | 653 | end; | |
| 654 | 654 | ||
| 655 | 655 | function CreatePort(PortGpio: LongWord): PLongWord; | |
| 656 | 656 | begin | |
| 657 | 657 | result := FpMmap(nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortGpio); | |
| 658 | 658 | end; | |
| 659 | 659 | ||
| 660 | 660 | procedure T_IO_Port.SetPinMode(a_io_pin, a_mode: byte); | |
| 661 | 661 | var | |
| 662 | 662 | fSel, shift : byte; | |
| 663 | 663 | iof : PLongWord; | |
| 664 | 664 | begin | |
| 665 | 665 | fSel := (a_io_pin div $A)*4 ; | |
| 666 | 666 | shift := (a_io_pin mod $A)*3 ; | |
| 667 | 667 | iof := Pointer(LongWord(Self.f_gpio)+fSel); | |
| 668 | 668 | case a_mode of | |
| 669 | 669 | INPUT : iof^ := iof^ and ($FFFFFFFF - (7 shl shift)); | |
| 670 | 670 | OUTPUT : iof^ := iof^ and ($FFFFFFFF - (7 shl shift)) or (1 shl shift); | |
| 671 | 671 | end; | |
| 672 | 672 | end; | |
| 673 | 673 | ||
| 674 | 674 | procedure T_IO_Port.SetBit(a_io_pin : byte); | |
| 675 | 675 | var | |
| 676 | 676 | iof : PLongWord; | |
| 677 | 677 | begin | |
| 678 | 678 | iof := Pointer(LongWord(Self.f_gpio) + GPSET + (a_io_pin shr 5) shl 2); | |
| 679 | 679 | iof^ := 1 shl a_io_pin; | |
| 680 | 680 | end; | |
| 681 | 681 | ||
| 682 | 682 | procedure T_IO_Port.ClearBit(a_io_pin : byte); | |
| 683 | 683 | var | |
| 684 | 684 | iof : PLongWord; | |
| 685 | 685 | begin | |
| 686 | 686 | iof := Pointer(LongWord(Self.f_gpio) + GPCLR + (a_io_pin shr 5) shl 2); | |
| 687 | 687 | iof^ := 1 shl a_io_pin; | |
| 688 | 688 | end; | |
| 689 | 689 | ||
| 690 | 690 | function T_IO_Port.GetBit(a_io_pin : byte):boolean; | |
| 691 | 691 | var | |
| 692 | 692 | iof : PLongWord; | |
| 693 | 693 | begin | |
| 694 | 694 | result := true; | |
| 695 | 695 | iof := Pointer(LongWord(Self.f_gpio) + GPLEV + (a_io_pin shr 5) shl 2); | |
| 696 | 696 | if (iof^ and (1 shl a_io_pin)) = 0 then result := false; | |
| 697 | 697 | end; | |
| 698 | 698 | end. | |
| 699 | 699 | ``` | |
| 700 | 700 | ||
| 701 | 701 | --- | |
| 702 | 702 | *From the Free Pascal wiki, page "Raspberry Pi : BerryClip", as it stood on 2020-02-23 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
