Coverage for /usr/lib/python3/dist-packages/gpiozero/pins/data.py: 38%

320 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-04-05 16:40 +0100

1# vim: set fileencoding=utf-8: 

2# 

3# GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins 

4# 

5# Copyright (c) 2016-2021 Dave Jones <dave@waveform.org.uk> 

6# Copyright (c) 2018-2021 Ben Nuttall <ben@bennuttall.com> 

7# Copyright (c) 2020 chrisruk <chrisrichardsonuk@gmail.com> 

8# Copyright (c) 2016-2019 Andrew Scheller <github@loowis.durge.org> 

9# 

10# SPDX-License-Identifier: BSD-3-Clause 

11 

12from __future__ import ( 

13 unicode_literals, 

14 absolute_import, 

15 print_function, 

16 division, 

17 ) 

18str = type('') 

19 

20import os 

21import sys 

22from textwrap import dedent 

23from itertools import cycle 

24from operator import attrgetter 

25from collections import namedtuple 

26 

27from ..exc import PinUnknownPi, PinMultiplePins, PinNoPins, PinInvalidPin 

28from ..devices import Device 

29 

30 

31# Some useful constants for describing pins 

32 

33V1_8 = '1V8' 

34V3_3 = '3V3' 

35V5 = '5V' 

36GND = 'GND' 

37NC = 'NC' # not connected 

38GPIO0 = 'GPIO0' 

39GPIO1 = 'GPIO1' 

40GPIO2 = 'GPIO2' 

41GPIO3 = 'GPIO3' 

42GPIO4 = 'GPIO4' 

43GPIO5 = 'GPIO5' 

44GPIO6 = 'GPIO6' 

45GPIO7 = 'GPIO7' 

46GPIO8 = 'GPIO8' 

47GPIO9 = 'GPIO9' 

48GPIO10 = 'GPIO10' 

49GPIO11 = 'GPIO11' 

50GPIO12 = 'GPIO12' 

51GPIO13 = 'GPIO13' 

52GPIO14 = 'GPIO14' 

53GPIO15 = 'GPIO15' 

54GPIO16 = 'GPIO16' 

55GPIO17 = 'GPIO17' 

56GPIO18 = 'GPIO18' 

57GPIO19 = 'GPIO19' 

58GPIO20 = 'GPIO20' 

59GPIO21 = 'GPIO21' 

60GPIO22 = 'GPIO22' 

61GPIO23 = 'GPIO23' 

62GPIO24 = 'GPIO24' 

63GPIO25 = 'GPIO25' 

64GPIO26 = 'GPIO26' 

65GPIO27 = 'GPIO27' 

66GPIO28 = 'GPIO28' 

67GPIO29 = 'GPIO29' 

68GPIO30 = 'GPIO30' 

69GPIO31 = 'GPIO31' 

70GPIO32 = 'GPIO32' 

71GPIO33 = 'GPIO33' 

72GPIO34 = 'GPIO34' 

73GPIO35 = 'GPIO35' 

74GPIO36 = 'GPIO36' 

75GPIO37 = 'GPIO37' 

76GPIO38 = 'GPIO38' 

77GPIO39 = 'GPIO39' 

78GPIO40 = 'GPIO40' 

79GPIO41 = 'GPIO41' 

80GPIO42 = 'GPIO42' 

81GPIO43 = 'GPIO43' 

82GPIO44 = 'GPIO44' 

83GPIO45 = 'GPIO45' 

84 

85# Board layout ASCII art 

86 

87REV1_BOARD = """\ 

88{style:white on green}+------------------{style:black on white}| |{style:white on green}--{style:on cyan}| |{style:on green}------+{style:reset} 

89{style:white on green}| {P1:{style} col2}{style:white on green} P1 {style:black on yellow}|C|{style:white on green} {style:on cyan}|A|{style:on green} |{style:reset} 

90{style:white on green}| {P1:{style} col1}{style:white on green} {style:black on yellow}+-+{style:white on green} {style:on cyan}+-+{style:on green} |{style:reset} 

91{style:white on green}| |{style:reset} 

92{style:white on green}| {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} 

93{style:white on green}| {style:on black}|SoC|{style:on green} {style:black on white}| USB{style:reset} 

94{style:white on green}| {style:on black}|D|{style:on green} {style:bold}Pi Model{style:normal} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} 

95{style:white on green}| {style:on black}|S|{style:on green} {style:bold}{model:3s}V{pcb_revision:3s}{style:normal} |{style:reset} 

96{style:white on green}| {style:on black}|I|{style:on green} {style:on black}|C|{style:black on white}+======{style:reset} 

97{style:white on green}| {style:on black}|S|{style:black on white}| Net{style:reset} 

98{style:white on green}| {style:on black}|I|{style:black on white}+======{style:reset} 

99{style:black on white}=pwr{style:on green} {style:on white}|HDMI|{style:white on green} |{style:reset} 

100{style:white on green}+----------------{style:black on white}| |{style:white on green}----------+{style:reset}""" 

101 

102REV2_BOARD = """\ 

103{style:white on green}+------------------{style:black on white}| |{style:white on green}--{style:on cyan}| |{style:on green}------+{style:reset} 

104{style:white on green}| {P1:{style} col2}{style:white on green} P1 {style:black on yellow}|C|{style:white on green} {style:on cyan}|A|{style:on green} |{style:reset} 

105{style:white on green}| {P1:{style} col1}{style:white on green} {style:black on yellow}+-+{style:white on green} {style:on cyan}+-+{style:on green} |{style:reset} 

106{style:white on green}| {P5:{style} col1}{style:white on green} |{style:reset} 

107{style:white on green}| P5 {P5:{style} col2}{style:white on green} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} 

108{style:white on green}| {style:on black}|SoC|{style:on green} {style:black on white}| USB{style:reset} 

109{style:white on green}| {style:on black}|D|{style:on green} {style:bold}Pi Model{style:normal} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} 

110{style:white on green}| {style:on black}|S|{style:on green} {style:bold}{model:3s}V{pcb_revision:3s}{style:normal} |{style:reset} 

111{style:white on green}| {style:on black}|I|{style:on green} {style:on black}|C|{style:black on white}+======{style:reset} 

112{style:white on green}| {style:on black}|S|{style:black on white}| Net{style:reset} 

113{style:white on green}| {style:on black}|I|{style:black on white}+======{style:reset} 

114{style:black on white}=pwr{style:on green} {style:on white}|HDMI|{style:white on green} |{style:reset} 

115{style:white on green}+----------------{style:black on white}| |{style:white on green}----------+{style:reset}""" 

116 

117A_BOARD = """\ 

118{style:white on green}+------------------{style:black on white}| |{style:white on green}--{style:on cyan}| |{style:on green}------+{style:reset} 

119{style:white on green}| {P1:{style} col2}{style:white on green} P1 {style:black on yellow}|C|{style:white on green} {style:on cyan}|A|{style:on green} |{style:reset} 

120{style:white on green}| {P1:{style} col1}{style:white on green} {style:black on yellow}+-+{style:white on green} {style:on cyan}+-+{style:on green} |{style:reset} 

121{style:white on green}| {P5:{style} col1}{style:white on green} |{style:reset} 

122{style:white on green}| P5 {P5:{style} col2}{style:white on green} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} 

123{style:white on green}| {style:on black}|SoC|{style:on green} {style:black on white}| USB{style:reset} 

124{style:white on green}| {style:on black}|D|{style:on green} {style:bold}Pi Model{style:normal} {style:on black}+---+{style:on green} {style:black on white}+===={style:reset} 

125{style:white on green}| {style:on black}|S|{style:on green} {style:bold}{model:3s}V{pcb_revision:3s}{style:normal} |{style:reset} 

126{style:white on green}| {style:on black}|I|{style:on green} {style:on black}|C|{style:on green} |{style:reset} 

127{style:white on green}| {style:on black}|S|{style:on green} |{style:reset} 

128{style:white on green}| {style:on black}|I|{style:on green} |{style:reset} 

129{style:black on white}=pwr{style:on green} {style:on white}|HDMI|{style:white on green} |{style:reset} 

130{style:white on green}+----------------{style:black on white}| |{style:white on green}----------+{style:reset}""" 

131 

132BPLUS_BOARD = """\ 

133{style:white on green},--------------------------------.{style:reset} 

134{style:white on green}| {J8:{style} col2}{style:white on green} J8 {style:black on white}+===={style:reset} 

135{style:white on green}| {J8:{style} col1}{style:white on green} {style:black on white}| USB{style:reset} 

136{style:white on green}| {style:black on white}+===={style:reset} 

137{style:white on green}| {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} |{style:reset} 

138{style:white on green}| {style:on black}+----+{style:on green} {style:black on white}+===={style:reset} 

139{style:white on green}| {style:on black}|D|{style:on green} {style:on black}|SoC |{style:on green} {style:black on white}| USB{style:reset} 

140{style:white on green}| {style:on black}|S|{style:on green} {style:on black}| |{style:on green} {style:black on white}+===={style:reset} 

141{style:white on green}| {style:on black}|I|{style:on green} {style:on black}+----+{style:on green} |{style:reset} 

142{style:white on green}| {style:on black}|C|{style:on green} {style:black on white}+======{style:reset} 

143{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| Net{style:reset} 

144{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} {style:black on white}+======{style:reset} 

145{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-------'{style:reset}""" 

146 

147B3PLUS_BOARD = """\ 

148{style:white on green},--------------------------------.{style:reset} 

149{style:white on green}| {J8:{style} col2}{style:white on green} J8 {style:black on white}+===={style:reset} 

150{style:white on green}| {J8:{style} col1}{style:white on green} PoE {style:black on white}| USB{style:reset} 

151{style:white on green}| {style:black on white} Wi {style:white on green} {POE:{style} row1}{style:on green} {style:black on white}+===={style:reset} 

152{style:white on green}| {style:black on white} Fi {style:white on green} {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} {POE:{style} row2}{style:on green} |{style:reset} 

153{style:white on green}| {style:black on white},----.{style:on green} {style:black on white}+===={style:reset} 

154{style:white on green}| {style:on black}|D|{style:on green} {style:black on white}|SoC |{style:on green} {style:black on white}| USB{style:reset} 

155{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| |{style:on green} {style:black on white}+===={style:reset} 

156{style:white on green}| {style:on black}|I|{style:on green} {style:black on white}`----'{style:white on green} |{style:reset} 

157{style:white on green}| {style:on black}|C|{style:on green} {style:black on white}+======{style:reset} 

158{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| Net{style:reset} 

159{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} {style:black on white}+======{style:reset} 

160{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-------'{style:reset}""" 

161 

162B4_BOARD = """\ 

163{style:white on green},--------------------------------.{style:reset} 

164{style:white on green}| {J8:{style} col2}{style:white on green} J8 {style:black on white}+======{style:reset} 

165{style:white on green}| {J8:{style} col1}{style:white on green} PoE {style:black on white}| Net{style:reset} 

166{style:white on green}| {style:black on white} Wi {style:white on green} {POE:{style} row1}{style:on green} {style:black on white}+======{style:reset} 

167{style:white on green}| {style:black on white} Fi {style:white on green} {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} {POE:{style} row2}{style:normal white on green} |{style:reset} 

168{style:white on green}| {style:black on white},----.{style:on green} {style:white on black}+---+{style:on green} {style:blue on white}+===={style:reset} 

169{style:white on green}| {style:on black}|D|{style:on green} {style:black on white}|SoC |{style:on green} {style:white on black}|RAM|{style:on green} {style:blue on white}|USB3{style:reset} 

170{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| |{style:on green} {style:white on black}| |{style:on green} {style:blue on white}+===={style:reset} 

171{style:white on green}| {style:on black}|I|{style:on green} {style:black on white}`----'{style:white on green} {style:white on black}+---+{style:on green} |{style:reset} 

172{style:white on green}| {style:on black}|C|{style:on green} {style:black on white}+===={style:reset} 

173{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}|USB2{style:reset} 

174{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|hd|{style:white on green} {style:black on white}|hd|{style:white on green} {style:on black}|I||A|{style:on green} {style:black on white}+===={style:reset} 

175{style:white on green}`-{style:black on white}| |{style:white on green}---{style:black on white}|m0|{style:white on green}---{style:black on white}|m1|{style:white on green}----{style:on black}|V|{style:on green}-------'{style:reset}""" 

176 

177APLUS_BOARD = """\ 

178{style:white on green},--------------------------.{style:reset} 

179{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} 

180{style:white on green}| {J8:{style} col1}{style:white on green} |{style:reset} 

181{style:white on green}| |{style:reset} 

182{style:white on green}| {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} |{style:reset} 

183{style:white on green}| {style:on black}+----+{style:on green} {style:black on white}+===={style:reset} 

184{style:white on green}| {style:on black}|D|{style:on green} {style:on black}|SoC |{style:on green} {style:black on white}| USB{style:reset} 

185{style:white on green}| {style:on black}|S|{style:on green} {style:on black}| |{style:on green} {style:black on white}+===={style:reset} 

186{style:white on green}| {style:on black}|I|{style:on green} {style:on black}+----+{style:on green} |{style:reset} 

187{style:white on green}| {style:on black}|C|{style:on green} |{style:reset} 

188{style:white on green}| {style:on black}|S|{style:on green} |{style:reset} 

189{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} |{style:reset} 

190{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-'{style:reset}""" 

191 

192A3PLUS_BOARD = """\ 

193{style:white on green},--------------------------.{style:reset} 

194{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} 

195{style:white on green}| {J8:{style} col1}{style:white on green} |{style:reset} 

196{style:white on green}| {style:black on white} Wi {style:white on green} |{style:reset} 

197{style:white on green}| {style:black on white} Fi {style:white on green} {style:bold}Pi Model {model:4s}V{pcb_revision:3s}{style:normal} |{style:reset} 

198{style:white on green}| {style:black on white},----.{style:on green} {style:black on white}+===={style:reset} 

199{style:white on green}| {style:on black}|D|{style:on green} {style:black on white}|SoC |{style:on green} {style:black on white}| USB{style:reset} 

200{style:white on green}| {style:on black}|S|{style:on green} {style:black on white}| |{style:on green} {style:black on white}+===={style:reset} 

201{style:white on green}| {style:on black}|I|{style:on green} {style:black on white}`----'{style:white on green} |{style:reset} 

202{style:white on green}| {style:on black}|C|{style:on green} |{style:reset} 

203{style:white on green}| {style:on black}|S|{style:on green} |{style:reset} 

204{style:white on green}| {style:black on white}pwr{style:white on green} {style:black on white}|HDMI|{style:white on green} {style:on black}|I||A|{style:on green} |{style:reset} 

205{style:white on green}`-{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}----{style:on black}|V|{style:on green}-'{style:reset}""" 

206 

207ZERO12_BOARD = """\ 

208{style:white on green},-------------------------.{style:reset} 

209{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} 

210{style:white on green}| {J8:{style} col1}{style:white on green} |{style:reset} 

211{style:black on white}---+{style:white on green} {style:on black}+---+{style:on green} {style:bold}PiZero{style:normal} |{style:reset} 

212{style:black on white} sd|{style:white on green} {style:on black}|SoC|{style:on green} {style:bold}V{pcb_revision:3s}{style:normal} |{style:reset} 

213{style:black on white}---+|hdmi|{style:white on green} {style:on black}+---+{style:on green} {style:black on white}usb{style:on green} {style:black on white}pwr{style:white on green} |{style:reset} 

214{style:white on green}`---{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}-'{style:reset}""" 

215 

216ZERO13_BOARD = """\ 

217{style:white on green}.-------------------------.{style:reset} 

218{style:white on green}| {J8:{style} col2}{style:white on green} J8 |{style:reset} 

219{style:white on green}| {J8:{style} col1}{style:white on green} {style:black on white}|c{style:reset} 

220{style:black on white}---+{style:white on green} {style:on black}+---+{style:on green} {style:bold}Pi{model:6s}{style:normal}{style:black on white}|s{style:reset} 

221{style:black on white} sd|{style:white on green} {style:on black}|SoC|{style:on green} {style:bold}V{pcb_revision:3s}{style:normal} {style:black on white}|i{style:reset} 

222{style:black on white}---+|hdmi|{style:white on green} {style:on black}+---+{style:on green} {style:black on white}usb{style:on green} {style:on white}pwr{style:white on green} |{style:reset} 

223{style:white on green}`---{style:black on white}| |{style:white on green}--------{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}-'{style:reset}""" 

224 

225CM_BOARD = """\ 

226{style:white on green}+---------------------------------------+{style:reset} 

227{style:white on green}| {style:yellow on black}O{style:bold white on green} Raspberry Pi {model:4s} {style:normal yellow on black}O{style:white on green} |{style:reset} 

228 {style:white on green}) Version {pcb_revision:3s} {style:on black}+---+{style:on green} ({style:reset} 

229{style:white on green}| {style:on black}|SoC|{style:on green} |{style:reset} 

230 {style:white on green}) {style:on black}+---+{style:on green} ({style:reset} 

231{style:white on green}| {style:on black}O{style:on green} _ {style:on black}O{style:on green} |{style:reset} 

232{style:white on green}||||||{style:reset} {style:white on green}||||||||||||||||||||||||||||||||||{style:reset}""" 

233 

234CM3PLUS_BOARD = """\ 

235{style:white on green}+---------------------------------------+{style:reset} 

236{style:white on green}| {style:yellow on black}O{style:bold white on green} Raspberry Pi {model:4s} {style:normal yellow on black}O{style:white on green} |{style:reset} 

237 {style:white on green}) Version {pcb_revision:3s} {style:black on white},---.{style:white on green} ({style:reset} 

238{style:white on green}| {style:black on white}|SoC|{style:white on green} |{style:reset} 

239 {style:white on green}) {style:black on white}`---'{style:white on green} ({style:reset} 

240{style:white on green}| {style:on black}O{style:on green} _ {style:on black}O{style:on green} |{style:reset} 

241{style:white on green}||||||{style:reset} {style:white on green}||||||||||||||||||||||||||||||||||{style:reset}""" 

242 

243CM4_BOARD = """\ 

244{style:white on green},--{style:black on white}csi1{style:white on green}---{style:black on white}dsi0{style:white on green}---{style:black on white}dsi1{style:white on green}-----------{style:bold},-------------.{style:normal}-----------.{style:reset} 

245{style:white on green}| {style:black on white}----{style:white on green} {style:black on white}----{style:white on green} {style:black on white}----{style:white on green} J2{J2:{style} col2}{style:bold white on green}|{style:yellow}O O{style:white}|{style:normal} |{style:reset} 

246{style:white on green}{style:black on white}c|{style:white on green} {style:bold yellow}O {style:white}Pi {model:4s} Rev {pcb_revision:3s}{style:normal} {J2:{style} col1}{style:bold white on green}| {style:normal black on white} Wi {style:white on green} {style:bold}|{style:normal} {style:bold yellow}O{style:normal white} |{style:reset} 

247{style:white on green}{style:black on white}s|{style:white on green} {style:bold}IO Board{style:normal} {style:bold}| {style:normal black on white} Fi {style:white on green} {style:bold}|{style:normal} |{style:reset} 

248{style:white on green}{style:black on white}i|{style:white on green} J6{J6:{style} col2}{style:bold white on green} | {style:normal white on black}+--+{style:on green}{style:bold}| {style:normal white on black}|P|{style:on green} |{style:reset} 

249{style:white on green}| J8 {J6:{style} col1}{style:bold white on green} | {style:normal black on white},----.{style:on green} {style:white on black}|eM|{style:bold on green}| {style:normal white on black}}}-{{{style:on green} |{style:reset} 

250{style:white on green}|{style:bold yellow}O{J8:{style} col2}{style:white on green} {style:bold yellow}O{style:white} | {style:normal black on white}|SoC |{style:on green} {style:white on black}|MC|{style:bold on green}| {style:normal white on black}|C|{style:on green} |{style:reset} 

251{style:white on green}| {J8:{style} col1}{style:white on green} PoE {style:bold}| {style:normal black on white}| |{style:on green} {style:white on black}+--+{style:bold on green}| {style:normal white on black}|I|{style:on green} |{style:reset} 

252{style:white on green}| {style:black on white},---.{style:white on green} {POE:{style} row1}{style:bold white on green} | {style:normal black on white}`----'{style:white on green} {style:bold}| {style:normal white on black}|e|{style:on green} |{style:reset} 

253{style:white on green}|{style:black on white}( ={style:on green}O{style:on white} |{style:white on green} {POE:{style} row2}{style:bold white on green} | {style:normal white on black}+----+{style:on green} {style:bold}|{style:normal} |{style:reset} 

254{style:white on green}| {style:black on white}) + |{style:white on green} {style:bold}|{style:yellow}O {style:normal white on black}|RAM |{style:on green} {style:bold yellow}O{style:white}|{style:normal} |{style:reset} 

255{style:white on green}|{style:black on white}( ={style:on green}O{style:on white} |{style:white on green} {style:bold}`--{style:normal white on black}+----+{style:bold on green}-----'{style:normal} |{style:reset} 

256{style:white on green}| {style:black on white}`---'{style:white on green} |{style:reset} 

257{style:white on green}| |{style:reset} 

258{style:white on green}| |{style:reset} 

259{style:white on green}| {style:bold yellow}O {style:normal black on white}|Net |{style:on green} {style:black on white}|USB|{style:on green} {style:black on white}|uSD|{style:white on green} {style:bold yellow}O{style:normal white on black}|p|{style:on green}|{style:reset} 

260{style:white on green}|{style:bold yellow}O {style:normal black on white}|HDMI|{style:on green} {style:black on white}|HDMI|{style:white on green} {style:bold yellow}O {style:normal black on white}| |{style:on green} {style:black on white}| 2 |{style:on green} {style:black on white}usb{style:white on green} {style:black on white}| |{style:white on green} {style:on black}|w|{style:on green}|{style:reset} 

261{style:white on green}`----{style:black on white}| 0 |{style:white on green}---{style:black on white}| 1 |{style:white on green}-------{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}-{style:black on white}| |{style:white on green}------------{style:white on black}|r|{style:on green}'{style:reset}""" 

262 

263P400_BOARD = """\ 

264 {style:white on red},------+----+----+----+----+---+--+--+--+--------------------+---.{style:reset} 

265 {style:white on red},' |{style:white on black}Net {style:white on red}|{style:white on black}USB {style:white on red}|{style:cyan on black}USB {style:white on red}|{style:cyan on black}USB {style:white on red}|{style:white on black}pwr{style:white on red}|{style:white on black}hd{style:white on red}|{style:white on black}hd{style:white on red}|{style:white on black}sd{style:white on red}|{J8:{style} col2}{style:white on red}| `.{style:reset} 

266 {style:white on red}/ {style:black}=={style:white} |{style:white on black} {style:white on red}|{style:white on black} 2 {style:white on red}|{style:cyan on black} 3 {style:white on red}|{style:cyan on black} 3 {style:white on red}|{style:white on black} {style:white on red}|{style:white on black}m1{style:white on red}|{style:white on black}m0{style:white on red}|{style:white on black} {style:white on red}|{J8:{style} col1}{style:white on red}| \\{style:reset} 

267{style:black on white},------------------------------------------------------------------------.{style:reset} 

268{style:black on white}| ___ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ {style:bold on white}o o {style:green}o{style:normal black}____ |{style:reset} 

269{style:black on white}| |Esc|F1{style:red}11{style:black}|F2{style:red}12{style:black}|F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10{style:red}o{style:black}|NumL|Pt{style:red}Sq{style:black}|Dl{style:red}In{style:black}| |{style:reset} 

270{style:black on white}| ___ ___ ____ ____ ____ ____ ____ ___ ____ ____ ____ ___ ____ _______ |{style:reset} 

271{style:black on white}| |¬ |! |" |£ |$ |% |^ |& {style:red}7{style:black}|* {style:red}8{style:black}|( {style:red}9{style:black}|) {style:red}*{style:black}|_ |+ |BkSpc | |{style:reset} 

272{style:black on white}| |` ||1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |<-- | |{style:reset} 

273{style:black on white}| _____ ___ ____ ____ ____ ____ ____ ___ ____ ____ ____ ____ __ ______ |{style:reset} 

274{style:black on white}| |Tab |Q |W |E |R |T |Y |U {style:red}4{style:black}|I {style:red}5{style:black}|O {style:red}6{style:black}|P {style:red}-{style:black}|{{ |}} |Enter | |{style:reset} 

275{style:black on white}| |->| | | | | | | | | | | |[ |] |<-' | |{style:reset} 

276{style:black on white}| ______ ____ ____ ____ ____ ____ ____ ___ ____ ____ ____ ____ __ | |{style:reset} 

277{style:black on white}| |Caps |A |S |D |F |G |H |J {style:red}1{style:black}|K {style:red}2{style:black}|L {style:red}3{style:black}|: {style:red}+{style:black}|@ |~ | | |{style:reset} 

278{style:black on white}| |Lock | | | | | | | | | |; |' |# | | |{style:reset} 

279{style:black on white}| _____ ___ ___ ____ ____ ____ ____ ____ ___ ____ ____ ____ __________ |{style:reset} 

280{style:black on white}| |Shift|| |Z |X |C |V |B |N |M {style:red}0{style:black}|< |> {style:red}.{style:black}|? {style:red}/{style:black}|Shift | |{style:reset} 

281{style:black on white}| |^ |\\ | | | | | | | |, |. |/ |^ | |{style:reset} 

282{style:black on white}| ____ ___ ____ ____ _______________________ ____ ____ _____ |{style:reset} 

283{style:black on white}| |Ctrl|{style:red}Fn{style:black} | {style:red}**{style:black} |Alt | |Alt |Ctrl|____|^{style:red}PgUp{style:black}|____ |{style:reset} 

284{style:black on white}| | | | {style:red}{{}}{style:black} | | | | |<{style:red}Hom{style:black}|v{style:red}PgDn{style:black}|>{style:red}End{style:black}| |{style:reset} 

285{style:black on white}`------------------------------------------------------------------------'{style:reset} 

286 Raspberry Pi {style:bold red}{model}{style:reset} Rev {pcb_revision}""" 

287 

288# Pin maps for various board revisions and headers 

289 

290REV1_P1 = { 

291# pin func pullup pin func pullup 

292 1: (V3_3, False), 2: (V5, False), 

293 3: (GPIO0, True), 4: (V5, False), 

294 5: (GPIO1, True), 6: (GND, False), 

295 7: (GPIO4, False), 8: (GPIO14, False), 

296 9: (GND, False), 10: (GPIO15, False), 

297 11: (GPIO17, False), 12: (GPIO18, False), 

298 13: (GPIO21, False), 14: (GND, False), 

299 15: (GPIO22, False), 16: (GPIO23, False), 

300 17: (V3_3, False), 18: (GPIO24, False), 

301 19: (GPIO10, False), 20: (GND, False), 

302 21: (GPIO9, False), 22: (GPIO25, False), 

303 23: (GPIO11, False), 24: (GPIO8, False), 

304 25: (GND, False), 26: (GPIO7, False), 

305 } 

306 

307REV2_P1 = { 

308 1: (V3_3, False), 2: (V5, False), 

309 3: (GPIO2, True), 4: (V5, False), 

310 5: (GPIO3, True), 6: (GND, False), 

311 7: (GPIO4, False), 8: (GPIO14, False), 

312 9: (GND, False), 10: (GPIO15, False), 

313 11: (GPIO17, False), 12: (GPIO18, False), 

314 13: (GPIO27, False), 14: (GND, False), 

315 15: (GPIO22, False), 16: (GPIO23, False), 

316 17: (V3_3, False), 18: (GPIO24, False), 

317 19: (GPIO10, False), 20: (GND, False), 

318 21: (GPIO9, False), 22: (GPIO25, False), 

319 23: (GPIO11, False), 24: (GPIO8, False), 

320 25: (GND, False), 26: (GPIO7, False), 

321 } 

322 

323REV2_P5 = { 

324 1: (V5, False), 2: (V3_3, False), 

325 3: (GPIO28, False), 4: (GPIO29, False), 

326 5: (GPIO30, False), 6: (GPIO31, False), 

327 7: (GND, False), 8: (GND, False), 

328 } 

329 

330PLUS_J8 = { 

331 1: (V3_3, False), 2: (V5, False), 

332 3: (GPIO2, True), 4: (V5, False), 

333 5: (GPIO3, True), 6: (GND, False), 

334 7: (GPIO4, False), 8: (GPIO14, False), 

335 9: (GND, False), 10: (GPIO15, False), 

336 11: (GPIO17, False), 12: (GPIO18, False), 

337 13: (GPIO27, False), 14: (GND, False), 

338 15: (GPIO22, False), 16: (GPIO23, False), 

339 17: (V3_3, False), 18: (GPIO24, False), 

340 19: (GPIO10, False), 20: (GND, False), 

341 21: (GPIO9, False), 22: (GPIO25, False), 

342 23: (GPIO11, False), 24: (GPIO8, False), 

343 25: (GND, False), 26: (GPIO7, False), 

344 27: (GPIO0, False), 28: (GPIO1, False), 

345 29: (GPIO5, False), 30: (GND, False), 

346 31: (GPIO6, False), 32: (GPIO12, False), 

347 33: (GPIO13, False), 34: (GND, False), 

348 35: (GPIO19, False), 36: (GPIO16, False), 

349 37: (GPIO26, False), 38: (GPIO20, False), 

350 39: (GND, False), 40: (GPIO21, False), 

351 } 

352 

353PLUS_POE = { 

354 1: ('TR01', False), 2: ('TR00', False), 

355 3: ('TR03', False), 4: ('TR02', False), 

356 } 

357 

358CM_SODIMM = { 

359 1: (GND, False), 2: ('EMMC DISABLE N', False), 

360 3: (GPIO0, False), 4: (NC, False), 

361 5: (GPIO1, False), 6: (NC, False), 

362 7: (GND, False), 8: (NC, False), 

363 9: (GPIO2, False), 10: (NC, False), 

364 11: (GPIO3, False), 12: (NC, False), 

365 13: (GND, False), 14: (NC, False), 

366 15: (GPIO4, False), 16: (NC, False), 

367 17: (GPIO5, False), 18: (NC, False), 

368 19: (GND, False), 20: (NC, False), 

369 21: (GPIO6, False), 22: (NC, False), 

370 23: (GPIO7, False), 24: (NC, False), 

371 25: (GND, False), 26: (GND, False), 

372 27: (GPIO8, False), 28: (GPIO28, False), 

373 29: (GPIO9, False), 30: (GPIO29, False), 

374 31: (GND, False), 32: (GND, False), 

375 33: (GPIO10, False), 34: (GPIO30, False), 

376 35: (GPIO11, False), 36: (GPIO31, False), 

377 37: (GND, False), 38: (GND, False), 

378 39: ('GPIO0-27 VREF', False), 40: ('GPIO0-27 VREF', False), 

379 # Gap in SODIMM pins 

380 41: ('GPIO28-45 VREF', False), 42: ('GPIO28-45 VREF', False), 

381 43: (GND, False), 44: (GND, False), 

382 45: (GPIO12, False), 46: (GPIO32, False), 

383 47: (GPIO13, False), 48: (GPIO33, False), 

384 49: (GND, False), 50: (GND, False), 

385 51: (GPIO14, False), 52: (GPIO34, False), 

386 53: (GPIO15, False), 54: (GPIO35, False), 

387 55: (GND, False), 56: (GND, False), 

388 57: (GPIO16, False), 58: (GPIO36, False), 

389 59: (GPIO17, False), 60: (GPIO37, False), 

390 61: (GND, False), 62: (GND, False), 

391 63: (GPIO18, False), 64: (GPIO38, False), 

392 65: (GPIO19, False), 66: (GPIO39, False), 

393 67: (GND, False), 68: (GND, False), 

394 69: (GPIO20, False), 70: (GPIO40, False), 

395 71: (GPIO21, False), 72: (GPIO41, False), 

396 73: (GND, False), 74: (GND, False), 

397 75: (GPIO22, False), 76: (GPIO42, False), 

398 77: (GPIO23, False), 78: (GPIO43, False), 

399 79: (GND, False), 80: (GND, False), 

400 81: (GPIO24, False), 82: (GPIO44, False), 

401 83: (GPIO25, False), 84: (GPIO45, False), 

402 85: (GND, False), 86: (GND, False), 

403 87: (GPIO26, False), 88: ('GPIO46 1V8', False), 

404 89: (GPIO27, False), 90: ('GPIO47 1V8', False), 

405 91: (GND, False), 92: (GND, False), 

406 93: ('DSI0 DN1', False), 94: ('DSI1 DP0', False), 

407 95: ('DSI0 DP1', False), 96: ('DSI1 DN0', False), 

408 97: (GND, False), 98: (GND, False), 

409 99: ('DSI0 DN0', False), 100: ('DSI1 CP', False), 

410 101: ('DSI0 DP0', False), 102: ('DSI1 CN', False), 

411 103: (GND, False), 104: (GND, False), 

412 105: ('DSI0 CN', False), 106: ('DSI1 DP3', False), 

413 107: ('DSI0 CP', False), 108: ('DSI1 DN3', False), 

414 109: (GND, False), 110: (GND, False), 

415 111: ('HDMI CK N', False), 112: ('DSI1 DP2', False), 

416 113: ('HDMI CK P', False), 114: ('DSI1 DN2', False), 

417 115: (GND, False), 116: (GND, False), 

418 117: ('HDMI D0 N', False), 118: ('DSI1 DP1', False), 

419 119: ('HDMI D0 P', False), 120: ('DSI1 DN1', False), 

420 121: (GND, False), 122: (GND, False), 

421 123: ('HDMI D1 N', False), 124: (NC, False), 

422 125: ('HDMI D1 P', False), 126: (NC, False), 

423 127: (GND, False), 128: (NC, False), 

424 129: ('HDMI D2 N', False), 130: (NC, False), 

425 131: ('HDMI D2 P', False), 132: (NC, False), 

426 133: (GND, False), 134: (GND, False), 

427 135: ('CAM1 DP3', False), 136: ('CAM0 DP0', False), 

428 137: ('CAM1 DN3', False), 138: ('CAM0 DN0', False), 

429 139: (GND, False), 140: (GND, False), 

430 141: ('CAM1 DP2', False), 142: ('CAM0 CP', False), 

431 143: ('CAM1 DN2', False), 144: ('CAM0 CN', False), 

432 145: (GND, False), 146: (GND, False), 

433 147: ('CAM1 CP', False), 148: ('CAM0 DP1', False), 

434 149: ('CAM1 CN', False), 150: ('CAM0 DN1', False), 

435 151: (GND, False), 152: (GND, False), 

436 153: ('CAM1 DP1', False), 154: (NC, False), 

437 155: ('CAM1 DN1', False), 156: (NC, False), 

438 157: (GND, False), 158: (NC, False), 

439 159: ('CAM1 DP0', False), 160: (NC, False), 

440 161: ('CAM1 DN0', False), 162: (NC, False), 

441 163: (GND, False), 164: (GND, False), 

442 165: ('USB DP', False), 166: ('TVDAC', False), 

443 167: ('USB DM', False), 168: ('USB OTGID', False), 

444 169: (GND, False), 170: (GND, False), 

445 171: ('HDMI CEC', False), 172: ('VC TRST N', False), 

446 173: ('HDMI SDA', False), 174: ('VC TDI', False), 

447 175: ('HDMI SCL', False), 176: ('VC TMS', False), 

448 177: ('RUN', False), 178: ('VC TDO', False), 

449 179: ('VDD CORE', False), 180: ('VC TCK', False), 

450 181: (GND, False), 182: (GND, False), 

451 183: (V1_8, False), 184: (V1_8, False), 

452 185: (V1_8, False), 186: (V1_8, False), 

453 187: (GND, False), 188: (GND, False), 

454 189: ('VDAC', False), 190: ('VDAC', False), 

455 191: (V3_3, False), 192: (V3_3, False), 

456 193: (V3_3, False), 194: (V3_3, False), 

457 195: (GND, False), 196: (GND, False), 

458 197: ('VBAT', False), 198: ('VBAT', False), 

459 199: ('VBAT', False), 200: ('VBAT', False), 

460 } 

461 

462CM3_SODIMM = CM_SODIMM.copy() 

463CM3_SODIMM.update({ 

464 4: ('NC / SDX VREF', False), 

465 6: ('NC / SDX VREF', False), 

466 8: (GND, False), 

467 10: ('NC / SDX CLK', False), 

468 12: ('NC / SDX CMD', False), 

469 14: (GND, False), 

470 16: ('NC / SDX D0', False), 

471 18: ('NC / SDX D1', False), 

472 20: (GND, False), 

473 22: ('NC / SDX D2', False), 

474 24: ('NC / SDX D3', False), 

475 88: ('HDMI HPD N 1V8', False), 

476 90: ('EMMC EN N 1V8', False), 

477 }) 

478 

479CM4_J6 = { 

480 1: ('1-2 CAM0+DISP0', False), 2: ('1-2 CAM0+DISP0', False), 

481 3: ('3-4 CAM0+DISP0', False), 4: ('3-4 CAM0+DISP0', False), 

482 } 

483 

484CM4_J2 = { 

485 1: ('1-2 DISABLE eMMC BOOT', False), 2: ('1-2 DISABLE eMMC BOOT', False), 

486 3: ('3-4 WRITE-PROT EEPROM', False), 4: ('3-4 WRITE-PROT EEPROM', False), 

487 5: ('UNKNOWN', False), 6: ('UNKNOWN', False), 

488 7: ('UNKNOWN', False), 8: ('UNKNOWN', False), 

489 9: ('UNKNOWN', False), 10: ('UNKNOWN', False), 

490 11: ('UNKNOWN', False), 12: ('UNKNOWN', False), 

491 13: ('UNKNOWN', False), 14: ('UNKNOWN', False), 

492 } 

493 

494# The following data is sourced from a combination of the following locations: 

495# 

496# http://elinux.org/RPi_HardwareHistory 

497# http://elinux.org/RPi_Low-level_peripherals 

498# https://git.drogon.net/?p=wiringPi;a=blob;f=wiringPi/wiringPi.c#l807 

499# https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md 

500 

501PI_REVISIONS = { 

502 # rev model pcb_rev released soc manufacturer ram storage usb eth wifi bt csi dsi headers board 

503 0x2: ('B', '1.0', '2012Q1', 'BCM2835', 'Egoman', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV1_P1}, REV1_BOARD, ), 

504 0x3: ('B', '1.0', '2012Q3', 'BCM2835', 'Egoman', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV1_P1}, REV1_BOARD, ), 

505 0x4: ('B', '2.0', '2012Q3', 'BCM2835', 'Sony', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), 

506 0x5: ('B', '2.0', '2012Q4', 'BCM2835', 'Qisda', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), 

507 0x6: ('B', '2.0', '2012Q4', 'BCM2835', 'Egoman', 256, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), 

508 0x7: ('A', '2.0', '2013Q1', 'BCM2835', 'Egoman', 256, 'SD', 1, 0, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, A_BOARD, ), 

509 0x8: ('A', '2.0', '2013Q1', 'BCM2835', 'Sony', 256, 'SD', 1, 0, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, A_BOARD, ), 

510 0x9: ('A', '2.0', '2013Q1', 'BCM2835', 'Qisda', 256, 'SD', 1, 0, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, A_BOARD, ), 

511 0xd: ('B', '2.0', '2012Q4', 'BCM2835', 'Egoman', 512, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), 

512 0xe: ('B', '2.0', '2012Q4', 'BCM2835', 'Sony', 512, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), 

513 0xf: ('B', '2.0', '2012Q4', 'BCM2835', 'Qisda', 512, 'SD', 2, 1, False, False, 1, 1, {'P1': REV2_P1, 'P5': REV2_P5}, REV2_BOARD, ), 

514 0x10: ('B+', '1.2', '2014Q3', 'BCM2835', 'Sony', 512, 'MicroSD', 4, 1, False, False, 1, 1, {'J8': PLUS_J8}, BPLUS_BOARD, ), 

515 0x11: ('CM', '1.1', '2014Q2', 'BCM2835', 'Sony', 512, 'eMMC', 1, 0, False, False, 2, 2, {'SODIMM': CM_SODIMM}, CM_BOARD, ), 

516 0x12: ('A+', '1.1', '2014Q4', 'BCM2835', 'Sony', 256, 'MicroSD', 1, 0, False, False, 1, 1, {'J8': PLUS_J8}, APLUS_BOARD, ), 

517 0x13: ('B+', '1.2', '2015Q1', 'BCM2835', 'Egoman', 512, 'MicroSD', 4, 1, False, False, 1, 1, {'J8': PLUS_J8}, BPLUS_BOARD, ), 

518 0x14: ('CM', '1.1', '2014Q2', 'BCM2835', 'Embest', 512, 'eMMC', 1, 0, False, False, 2, 2, {'SODIMM': CM_SODIMM}, CM_BOARD, ), 

519 0x15: ('A+', '1.1', '2014Q4', 'BCM2835', 'Embest', 256, 'MicroSD', 1, 0, False, False, 1, 1, {'J8': PLUS_J8}, APLUS_BOARD, ), 

520 } 

521 

522 

523# ANSI color codes, for the pretty printers (nothing comprehensive, just enough 

524# for our purposes) 

525 

526class Style(object): 

527 def __init__(self, color=None): 

528 self.color = self._term_supports_color() if color is None else bool(color) 

529 self.effects = { 

530 'reset': 0, 

531 'bold': 1, 

532 'normal': 22, 

533 } 

534 self.colors = { 

535 'black': 0, 

536 'red': 1, 

537 'green': 2, 

538 'yellow': 3, 

539 'blue': 4, 

540 'magenta': 5, 

541 'cyan': 6, 

542 'white': 7, 

543 'default': 9, 

544 } 

545 

546 @staticmethod 

547 def _term_supports_color(): 

548 try: 

549 stdout_fd = sys.stdout.fileno() 

550 except IOError: 

551 return False 

552 else: 

553 is_a_tty = os.isatty(stdout_fd) 

554 is_windows = sys.platform.startswith('win') 

555 return is_a_tty and not is_windows 

556 

557 @classmethod 

558 def from_style_content(cls, format_spec): 

559 specs = set(format_spec.split()) 

560 style = specs & {'mono', 'color'} 

561 content = specs - style 

562 if len(style) > 1: 

563 raise ValueError('cannot specify both mono and color styles') 

564 try: 

565 style = style.pop() 

566 except KeyError: 

567 style = 'color' if cls._term_supports_color() else 'mono' 

568 if len(content) > 1: 

569 raise ValueError('cannot specify more than one content element') 

570 try: 

571 content = content.pop() 

572 except KeyError: 

573 content = 'full' 

574 return cls(style == 'color'), content 

575 

576 def __call__(self, format_spec): 

577 specs = format_spec.split() 

578 codes = [] 

579 fore = True 

580 for spec in specs: 

581 if spec == 'on': 

582 fore = False 

583 else: 

584 try: 

585 codes.append(self.effects[spec]) 

586 except KeyError: 

587 try: 

588 if fore: 

589 codes.append(30 + self.colors[spec]) 

590 else: 

591 codes.append(40 + self.colors[spec]) 

592 except KeyError: 

593 raise ValueError( 

594 'invalid format specification "%s"' % spec) 

595 if self.color: 

596 return '\x1b[%sm' % (';'.join(str(code) for code in codes)) 

597 else: 

598 return '' 

599 

600 def __format__(self, format_spec): 

601 if format_spec == '': 

602 return 'color' if self.color else 'mono' 

603 else: 

604 return self(format_spec) 

605 

606 

607class PinInfo(namedtuple('PinInfo', ( 

608 'number', 

609 'function', 

610 'pull_up', 

611 'row', 

612 'col', 

613 ))): 

614 """ 

615 This class is a :func:`~collections.namedtuple` derivative used to 

616 represent information about a pin present on a GPIO header. The following 

617 attributes are defined: 

618 

619 .. attribute:: number 

620 

621 An integer containing the physical pin number on the header (starting 

622 from 1 in accordance with convention). 

623 

624 .. attribute:: function 

625 

626 A string describing the function of the pin. Some common examples 

627 include "GND" (for pins connecting to ground), "3V3" (for pins which 

628 output 3.3 volts), "GPIO9" (for GPIO9 in the Broadcom numbering 

629 scheme), etc. 

630 

631 .. attribute:: pull_up 

632 

633 A bool indicating whether the pin has a physical pull-up resistor 

634 permanently attached (this is usually :data:`False` but GPIO2 and GPIO3 

635 are *usually* :data:`True`). This is used internally by gpiozero to 

636 raise errors when pull-down is requested on a pin with a physical 

637 pull-up resistor. 

638 

639 .. attribute:: row 

640 

641 An integer indicating on which row the pin is physically located in 

642 the header (1-based) 

643 

644 .. attribute:: col 

645 

646 An integer indicating in which column the pin is physically located 

647 in the header (1-based) 

648 """ 

649 __slots__ = () # workaround python issue #24931 

650 

651 

652class HeaderInfo(namedtuple('HeaderInfo', ( 

653 'name', 

654 'rows', 

655 'columns', 

656 'pins', 

657 ))): 

658 """ 

659 This class is a :func:`~collections.namedtuple` derivative used to 

660 represent information about a pin header on a board. The object can be used 

661 in a format string with various custom specifications:: 

662 

663 from gpiozero import * 

664 

665 print('{0}'.format(pi_info().headers['J8'])) 

666 print('{0:full}'.format(pi_info().headers['J8'])) 

667 print('{0:col2}'.format(pi_info().headers['P1'])) 

668 print('{0:row1}'.format(pi_info().headers['P1'])) 

669 

670 "color" and "mono" can be prefixed to format specifications to force the 

671 use of `ANSI color codes`_. If neither is specified, ANSI codes will only 

672 be used if stdout is detected to be a tty:: 

673 

674 print('{0:color row2}'.format(pi_info().headers['J8'])) # force use of ANSI codes 

675 print('{0:mono row2}'.format(pi_info().headers['P1'])) # force plain ASCII 

676 

677 The following attributes are defined: 

678 

679 .. automethod:: pprint 

680 

681 .. attribute:: name 

682 

683 The name of the header, typically as it appears silk-screened on the 

684 board (e.g. "P1" or "J8"). 

685 

686 .. attribute:: rows 

687 

688 The number of rows on the header. 

689 

690 .. attribute:: columns 

691 

692 The number of columns on the header. 

693 

694 .. attribute:: pins 

695 

696 A dictionary mapping physical pin numbers to :class:`PinInfo` tuples. 

697 

698 .. _ANSI color codes: https://en.wikipedia.org/wiki/ANSI_escape_code 

699 """ 

700 __slots__ = () # workaround python issue #24931 

701 

702 def _func_style(self, function, style): 

703 if function == V5: 

704 return style('bold red') 

705 elif function in (V3_3, V1_8): 

706 return style('bold cyan') 

707 elif function in (GND, NC): 

708 return style('bold black') 

709 elif function.startswith('GPIO') and function[4:].isdigit(): 

710 return style('bold green') 

711 else: 

712 return style('yellow') 

713 

714 def _format_full(self, style): 

715 Cell = namedtuple('Cell', ('content', 'align', 'style')) 

716 

717 lines = [] 

718 for row in range(self.rows): 

719 line = [] 

720 for col in range(self.columns): 

721 pin = (row * self.columns) + col + 1 

722 try: 

723 pin = self.pins[pin] 

724 cells = [ 

725 Cell(pin.function, '><'[col % 2], self._func_style(pin.function, style)), 

726 Cell('(%d)' % pin.number, '><'[col % 2], ''), 

727 ] 

728 if col % 2: 

729 cells = reversed(cells) 

730 line.extend(cells) 

731 except KeyError: 

732 line.append(Cell('', '<', '')) 

733 lines.append(line) 

734 cols = list(zip(*lines)) 

735 col_lens = [max(len(cell.content) for cell in col) for col in cols] 

736 lines = [ 

737 ' '.join( 

738 '{cell.style}{cell.content:{cell.align}{width}s}{style:reset}'.format( 

739 cell=cell, width=width, style=style) 

740 for cell, width, align in zip(line, col_lens, cycle('><'))) 

741 for line in lines 

742 ] 

743 return '\n'.join(lines) 

744 

745 def _format_pin(self, pin, style): 

746 return ''.join(( 

747 style('on black'), 

748 ( 

749 ' ' if pin is None else 

750 self._func_style(pin.function, style) + 

751 ('1' if pin.number == 1 else 'o') 

752 ), 

753 style('reset') 

754 )) 

755 

756 def _format_row(self, row, style): 

757 if row > self.rows: 

758 raise ValueError('invalid row %d for header %s' % (row, self.name)) 

759 start_pin = (row - 1) * self.columns + 1 

760 return ''.join( 

761 self._format_pin(pin, style) 

762 for n in range(start_pin, start_pin + self.columns) 

763 for pin in (self.pins.get(n),) 

764 ) 

765 

766 def _format_col(self, col, style): 

767 if col > self.columns: 

768 raise ValueError('invalid col %d for header %s' % (col, self.name)) 

769 return ''.join( 

770 self._format_pin(pin, style) 

771 for n in range(col, self.rows * self.columns + 1, self.columns) 

772 for pin in (self.pins.get(n),) 

773 ) 

774 

775 def __format__(self, format_spec): 

776 style, content = Style.from_style_content(format_spec) 

777 if content == 'full': 

778 return self._format_full(style) 

779 elif content.startswith('row') and content[3:].isdigit(): 

780 return self._format_row(int(content[3:]), style) 

781 elif content.startswith('col') and content[3:].isdigit(): 

782 return self._format_col(int(content[3:]), style) 

783 else: 

784 raise ValueError('Invalid format specifier') 

785 

786 def pprint(self, color=None): 

787 """ 

788 Pretty-print a diagram of the header pins. 

789 

790 If *color* is :data:`None` (the default, the diagram will include ANSI 

791 color codes if stdout is a color-capable terminal). Otherwise *color* 

792 can be set to :data:`True` or :data:`False` to force color or 

793 monochrome output. 

794 """ 

795 print('{0:{style} full}'.format(self, style=Style(color))) 

796 

797 

798class PiBoardInfo(namedtuple('PiBoardInfo', ( 

799 'revision', 

800 'model', 

801 'pcb_revision', 

802 'released', 

803 'soc', 

804 'manufacturer', 

805 'memory', 

806 'storage', 

807 'usb', 

808 'usb3', 

809 'ethernet', 

810 'eth_speed', 

811 'wifi', 

812 'bluetooth', 

813 'csi', 

814 'dsi', 

815 'headers', 

816 'board', 

817 ))): 

818 """ 

819 This class is a :func:`~collections.namedtuple` derivative used to 

820 represent information about a particular model of Raspberry Pi. While it is 

821 a tuple, it is strongly recommended that you use the following named 

822 attributes to access the data contained within. The object can be used 

823 in format strings with various custom format specifications:: 

824 

825 from gpiozero import * 

826 

827 print('{0}'.format(pi_info())) 

828 print('{0:full}'.format(pi_info())) 

829 print('{0:board}'.format(pi_info())) 

830 print('{0:specs}'.format(pi_info())) 

831 print('{0:headers}'.format(pi_info())) 

832 

833 "color" and "mono" can be prefixed to format specifications to force the 

834 use of `ANSI color codes`_. If neither is specified, ANSI codes will only 

835 be used if stdout is detected to be a tty:: 

836 

837 print('{0:color board}'.format(pi_info())) # force use of ANSI codes 

838 print('{0:mono board}'.format(pi_info())) # force plain ASCII 

839 

840 .. _ANSI color codes: https://en.wikipedia.org/wiki/ANSI_escape_code 

841 

842 .. automethod:: physical_pin 

843 

844 .. automethod:: physical_pins 

845 

846 .. automethod:: pprint 

847 

848 .. automethod:: pulled_up 

849 

850 .. automethod:: to_gpio 

851 

852 .. attribute:: revision 

853 

854 A string indicating the revision of the Pi. This is unique to each 

855 revision and can be considered the "key" from which all other 

856 attributes are derived. However, in itself the string is fairly 

857 meaningless. 

858 

859 .. attribute:: model 

860 

861 A string containing the model of the Pi (for example, "B", "B+", "A+", 

862 "2B", "CM" (for the Compute Module), or "Zero"). 

863 

864 .. attribute:: pcb_revision 

865 

866 A string containing the PCB revision number which is silk-screened onto 

867 the Pi (on some models). 

868 

869 .. note:: 

870 

871 This is primarily useful to distinguish between the model B 

872 revision 1.0 and 2.0 (not to be confused with the model 2B) which 

873 had slightly different pinouts on their 26-pin GPIO headers. 

874 

875 .. attribute:: released 

876 

877 A string containing an approximate release date for this revision of 

878 the Pi (formatted as yyyyQq, e.g. 2012Q1 means the first quarter of 

879 2012). 

880 

881 .. attribute:: soc 

882 

883 A string indicating the SoC (`system on a chip`_) that this revision 

884 of the Pi is based upon. 

885 

886 .. attribute:: manufacturer 

887 

888 A string indicating the name of the manufacturer (usually "Sony" but a 

889 few others exist). 

890 

891 .. attribute:: memory 

892 

893 An integer indicating the amount of memory (in Mb) connected to the 

894 SoC. 

895 

896 .. note:: 

897 

898 This can differ substantially from the amount of RAM available 

899 to the operating system as the GPU's memory is shared with the 

900 CPU. When the camera module is activated, at least 128Mb of RAM 

901 is typically reserved for the GPU. 

902 

903 .. attribute:: storage 

904 

905 A string indicating the type of bootable storage used with this 

906 revision of Pi, e.g. "SD", "MicroSD", or "eMMC" (for the Compute 

907 Module). 

908 

909 .. attribute:: usb 

910 

911 An integer indicating how many USB ports are physically present on 

912 this revision of the Pi, of any type. 

913 

914 .. note:: 

915 

916 This does *not* include the micro-USB or USB-C port used to power 

917 the Pi. 

918 

919 .. attribute:: usb3 

920 

921 An integer indicating how many of the USB ports are USB3 ports on this 

922 revision of the Pi. 

923 

924 .. attribute:: ethernet 

925 

926 An integer indicating how many Ethernet ports are physically present 

927 on this revision of the Pi. 

928 

929 .. attribute:: eth_speed 

930 

931 An integer indicating the maximum speed (in Mbps) of the Ethernet ports 

932 (if any). If no Ethernet ports are present, this is 0. 

933 

934 .. attribute:: wifi 

935 

936 A bool indicating whether this revision of the Pi has wifi built-in. 

937 

938 .. attribute:: bluetooth 

939 

940 A bool indicating whether this revision of the Pi has bluetooth 

941 built-in. 

942 

943 .. attribute:: csi 

944 

945 An integer indicating the number of CSI (camera) ports available on 

946 this revision of the Pi. 

947 

948 .. attribute:: dsi 

949 

950 An integer indicating the number of DSI (display) ports available on 

951 this revision of the Pi. 

952 

953 .. attribute:: headers 

954 

955 A dictionary which maps header labels to :class:`HeaderInfo` tuples. 

956 For example, to obtain information about header P1 you would query 

957 ``headers['P1']``. To obtain information about pin 12 on header J8 you 

958 would query ``headers['J8'].pins[12]``. 

959 

960 A rendered version of this data can be obtained by using the 

961 :class:`PiBoardInfo` object in a format string:: 

962 

963 from gpiozero import * 

964 print('{0:headers}'.format(pi_info())) 

965 

966 .. attribute:: board 

967 

968 An ASCII art rendition of the board, primarily intended for console 

969 pretty-print usage. A more usefully rendered version of this data can 

970 be obtained by using the :class:`PiBoardInfo` object in a format 

971 string. For example:: 

972 

973 from gpiozero import * 

974 print('{0:board}'.format(pi_info())) 

975 

976 .. _system on a chip: https://en.wikipedia.org/wiki/System_on_a_chip 

977 """ 

978 __slots__ = () # workaround python issue #24931 

979 

980 @classmethod 

981 def from_revision(cls, revision): 

982 if revision & 0x800000: 982 ↛ 1177line 982 didn't jump to line 1177, because the condition on line 982 was never false

983 # New-style revision, parse information from bit-pattern: 

984 # 

985 # MSB -----------------------> LSB 

986 # NOQuuuWuFMMMCCCCPPPPTTTTTTTTRRRR 

987 # 

988 # N - Overvoltage (0=allowed, 1=disallowed) 

989 # O - OTP programming (0=allowed, 1=disallowed) 

990 # Q - OTP read (0=allowed, 1=disallowed) 

991 # u - Unused 

992 # W - Warranty bit (0=intact, 1=voided by overclocking) 

993 # F - New flag (1=valid new-style revision, 0=old-style) 

994 # MMM - Memory size (0=256, 1=512, 2=1024) 

995 # CCCC - Manufacturer (0=Sony, 1=Egoman, 2=Embest, 3=Sony Japan, 4=Embest, 5=Stadium) 

996 # PPPP - Processor (0=2835, 1=2836, 2=2837) 

997 # TTTTTTTT - Type (0=A, 1=B, 2=A+, 3=B+, 4=2B, 5=Alpha (??), 6=CM, 

998 # 8=3B, 9=Zero, 10=CM3, 12=Zero W, 13=3B+, 14=3A+) 

999 # RRRR - Revision (0, 1, 2, etc.) 

1000 revcode_memory = (revision & 0x700000) >> 20 

1001 revcode_manufacturer = (revision & 0xf0000) >> 16 

1002 revcode_processor = (revision & 0xf000) >> 12 

1003 revcode_type = (revision & 0xff0) >> 4 

1004 revcode_revision = (revision & 0x0f) 

1005 model = { 

1006 0x0: 'A', 

1007 0x1: 'B', 

1008 0x2: 'A+', 

1009 0x3: 'B+', 

1010 0x4: '2B', 

1011 0x6: 'CM', 

1012 0x8: '3B', 

1013 0x9: 'Zero', 

1014 0xa: 'CM3', 

1015 0xc: 'Zero W', 

1016 0xd: '3B+', 

1017 0xe: '3A+', 

1018 0x10: 'CM3+', 

1019 0x11: '4B', 

1020 0x13: '400', 

1021 0x14: 'CM4', 

1022 }.get(revcode_type, '???') 

1023 if model in ('A', 'B'): 1023 ↛ 1024line 1023 didn't jump to line 1024, because the condition on line 1023 was never true

1024 pcb_revision = { 

1025 0: '1.0', # is this right? 

1026 1: '1.0', 

1027 2: '2.0', 

1028 }.get(revcode_revision, 'Unknown') 

1029 else: 

1030 pcb_revision = '1.%d' % revcode_revision 

1031 soc = { 

1032 0: 'BCM2835', 

1033 1: 'BCM2836', 

1034 2: 'BCM2837', 

1035 3: 'BCM2711', 

1036 }.get(revcode_processor, 'Unknown') 

1037 manufacturer = { 

1038 0: 'Sony', 

1039 1: 'Egoman', 

1040 2: 'Embest', 

1041 3: 'Sony Japan', 

1042 4: 'Embest', 

1043 5: 'Stadium', 

1044 }.get(revcode_manufacturer, 'Unknown') 

1045 memory = { 

1046 0: 256, 

1047 1: 512, 

1048 2: 1024, 

1049 3: 2048, 

1050 4: 4096, 

1051 5: 8192, 

1052 }.get(revcode_memory, None) 

1053 released = { 

1054 'A': '2013Q1', 

1055 'B': '2012Q1' if pcb_revision == '1.0' else '2012Q4', 

1056 'A+': '2014Q4' if memory == 512 else '2016Q3', 

1057 'B+': '2014Q3', 

1058 '2B': '2015Q1' if pcb_revision in ('1.0', '1.1') else '2016Q3', 

1059 'CM': '2014Q2', 

1060 '3B': '2016Q1' if manufacturer in ('Sony', 'Embest') else '2016Q4', 

1061 'Zero': '2015Q4' if pcb_revision == '1.2' else '2016Q2', 

1062 'CM3': '2017Q1', 

1063 'Zero W': '2017Q1', 

1064 '3B+': '2018Q1', 

1065 '3A+': '2018Q4', 

1066 'CM3+': '2019Q1', 

1067 '4B': '2020Q2' if memory == 8192 else '2019Q2', 

1068 'CM4': '2020Q4', 

1069 '400': '2020Q4', 

1070 }.get(model, 'Unknown') 

1071 storage = { 

1072 'A': 'SD', 

1073 'B': 'SD', 

1074 'CM': 'eMMC', 

1075 'CM3': 'eMMC / off-board', 

1076 'CM3+': 'eMMC / off-board', 

1077 'CM4': 'eMMC / off-board', 

1078 }.get(model, 'MicroSD') 

1079 usb = { 

1080 'A': 1, 

1081 'A+': 1, 

1082 'Zero': 1, 

1083 'Zero W': 1, 

1084 'B': 2, 

1085 'CM': 1, 

1086 'CM3': 1, 

1087 '3A+': 1, 

1088 'CM3+': 1, 

1089 'CM4': 2, 

1090 '400': 3, 

1091 }.get(model, 4) 

1092 usb3 = { 

1093 '4B': 2, 

1094 '400': 2, 

1095 }.get(model, 0) 

1096 ethernet = { 

1097 'A': 0, 

1098 'A+': 0, 

1099 'Zero': 0, 

1100 'Zero W': 0, 

1101 'CM': 0, 

1102 'CM3': 0, 

1103 '3A+': 0, 

1104 'CM3+': 0, 

1105 }.get(model, 1) 

1106 eth_speed = { 

1107 'B': 100, 

1108 'B+': 100, 

1109 '2B': 100, 

1110 '3B': 100, 

1111 '3B+': 300, 

1112 '4B': 1000, 

1113 '400': 1000, 

1114 'CM4': 1000, 

1115 }.get(model, 0) 

1116 wifi = { 

1117 '3B': True, 

1118 'Zero W': True, 

1119 '3B+': True, 

1120 '3A+': True, 

1121 '4B': True, 

1122 '400': True, 

1123 'CM4': True, 

1124 }.get(model, False) 

1125 bluetooth = { 

1126 '3B': True, 

1127 'Zero W': True, 

1128 '3B+': True, 

1129 '3A+': True, 

1130 '4B': True, 

1131 '400': True, 

1132 'CM4': True, 

1133 }.get(model, False) 

1134 csi = { 

1135 'Zero': 0 if pcb_revision == '1.0' else 1, 

1136 'Zero W': 1, 

1137 'CM': 2, 

1138 'CM3': 2, 

1139 'CM3+': 2, 

1140 '400': 0, 

1141 'CM4': 2, 

1142 }.get(model, 1) 

1143 dsi = { 

1144 'Zero': 0, 

1145 'Zero W': 0, 

1146 'CM': 2, 

1147 'CM3': 2, 

1148 'CM3+': 2, 

1149 }.get(model, csi) 

1150 headers = { 

1151 'A': {'P1': REV2_P1, 'P5': REV2_P5}, 

1152 'B': {'P1': REV1_P1} if pcb_revision == '1.0' else {'P1': REV2_P1, 'P5': REV2_P5}, 

1153 'CM': {'SODIMM': CM_SODIMM}, 

1154 'CM3': {'SODIMM': CM3_SODIMM}, 

1155 'CM3+': {'SODIMM': CM3_SODIMM}, 

1156 '3B+': {'J8': PLUS_J8, 'POE': PLUS_POE}, 

1157 '4B': {'J8': PLUS_J8, 'POE': PLUS_POE}, 

1158 'CM4': {'J8': PLUS_J8, 'J2': CM4_J2, 'J6': CM4_J6, 'POE': PLUS_POE}, 

1159 }.get(model, {'J8': PLUS_J8}) 

1160 board = { 

1161 'A': A_BOARD, 

1162 'B': REV1_BOARD if pcb_revision == '1.0' else REV2_BOARD, 

1163 'A+': APLUS_BOARD, 

1164 'CM': CM_BOARD, 

1165 'CM3': CM_BOARD, 

1166 'CM3+': CM3PLUS_BOARD, 

1167 'Zero': ZERO12_BOARD if pcb_revision == '1.2' else ZERO13_BOARD, 

1168 'Zero W': ZERO13_BOARD, 

1169 '3A+': A3PLUS_BOARD, 

1170 '3B+': B3PLUS_BOARD, 

1171 '4B': B4_BOARD, 

1172 'CM4': CM4_BOARD, 

1173 '400': P400_BOARD, 

1174 }.get(model, BPLUS_BOARD) 

1175 else: 

1176 # Old-style revision, use the lookup table 

1177 try: 

1178 ( 

1179 model, 

1180 pcb_revision, 

1181 released, 

1182 soc, 

1183 manufacturer, 

1184 memory, 

1185 storage, 

1186 usb, 

1187 ethernet, 

1188 wifi, 

1189 bluetooth, 

1190 csi, 

1191 dsi, 

1192 headers, 

1193 board, 

1194 ) = PI_REVISIONS[revision] 

1195 usb3 = 0 

1196 eth_speed = ethernet * 100 

1197 except KeyError: 

1198 raise PinUnknownPi('unknown old-style revision "%x"' % revision) 

1199 headers = { 

1200 header: HeaderInfo(name=header, rows=max(header_data) // 2, columns=2, pins={ 

1201 number: PinInfo( 

1202 number=number, function=function, pull_up=pull_up, 

1203 row=row + 1, col=col + 1) 

1204 for number, (function, pull_up) in header_data.items() 

1205 for row, col in (divmod(number - 1, 2),) 

1206 }) 

1207 for header, header_data in headers.items() 

1208 } 

1209 return cls( 

1210 '%04x' % revision, 

1211 model, 

1212 pcb_revision, 

1213 released, 

1214 soc, 

1215 manufacturer, 

1216 memory, 

1217 storage, 

1218 usb, 

1219 usb3, 

1220 ethernet, 

1221 eth_speed, 

1222 wifi, 

1223 bluetooth, 

1224 csi, 

1225 dsi, 

1226 headers, 

1227 board, 

1228 ) 

1229 

1230 def physical_pins(self, function): 

1231 """ 

1232 Return the physical pins supporting the specified *function* as tuples 

1233 of ``(header, pin_number)`` where *header* is a string specifying the 

1234 header containing the *pin_number*. Note that the return value is a 

1235 :class:`set` which is not indexable. Use :func:`physical_pin` if you 

1236 are expecting a single return value. 

1237 

1238 :param str function: 

1239 The pin function you wish to search for. Usually this is something 

1240 like "GPIO9" for Broadcom GPIO pin 9, or "GND" for all the pins 

1241 connecting to electrical ground. 

1242 """ 

1243 return { 

1244 (header, pin.number) 

1245 for (header, info) in self.headers.items() 

1246 for pin in info.pins.values() 

1247 if pin.function == function 

1248 } 

1249 

1250 def physical_pin(self, function): 

1251 """ 

1252 Return the physical pin supporting the specified *function*. If no pins 

1253 support the desired *function*, this function raises :exc:`PinNoPins`. 

1254 If multiple pins support the desired *function*, :exc:`PinMultiplePins` 

1255 will be raised (use :func:`physical_pins` if you expect multiple pins 

1256 in the result, such as for electrical ground). 

1257 

1258 :param str function: 

1259 The pin function you wish to search for. Usually this is something 

1260 like "GPIO9" for Broadcom GPIO pin 9. 

1261 """ 

1262 result = self.physical_pins(function) 

1263 if len(result) > 1: 1263 ↛ 1264line 1263 didn't jump to line 1264, because the condition on line 1263 was never true

1264 raise PinMultiplePins('multiple pins can be used for %s' % function) 

1265 elif result: 1265 ↛ 1268line 1265 didn't jump to line 1268, because the condition on line 1265 was never false

1266 return result.pop() 

1267 else: 

1268 raise PinNoPins('no pins can be used for %s' % function) 

1269 

1270 def pulled_up(self, function): 

1271 """ 

1272 Returns a bool indicating whether a physical pull-up is attached to 

1273 the pin supporting the specified *function*. Either :exc:`PinNoPins` 

1274 or :exc:`PinMultiplePins` may be raised if the function is not 

1275 associated with a single pin. 

1276 

1277 :param str function: 

1278 The pin function you wish to determine pull-up for. Usually this is 

1279 something like "GPIO9" for Broadcom GPIO pin 9. 

1280 """ 

1281 try: 

1282 header, number = self.physical_pin(function) 

1283 except PinNoPins: 

1284 return False 

1285 else: 

1286 return self.headers[header].pins[number].pull_up 

1287 

1288 def to_gpio(self, spec): 

1289 """ 

1290 Parses a pin *spec*, returning the equivalent Broadcom GPIO port number 

1291 or raising a :exc:`ValueError` exception if the spec does not represent 

1292 a GPIO port. 

1293 

1294 The *spec* may be given in any of the following forms: 

1295 

1296 * An integer, which will be accepted as a GPIO number 

1297 * 'GPIOn' where n is the GPIO number 

1298 * 'WPIn' where n is the `wiringPi`_ pin number 

1299 * 'BCMn' where n is the GPIO number (alias of GPIOn) 

1300 * 'BOARDn' where n is the physical pin number on the main header 

1301 * 'h:n' where h is the header name and n is the physical pin number 

1302 (for example J8:5 is physical pin 5 on header J8, which is the main 

1303 header on modern Raspberry Pis) 

1304 

1305 .. _wiringPi: http://wiringpi.com/pins/ 

1306 """ 

1307 if isinstance(spec, int): 1307 ↛ 1313line 1307 didn't jump to line 1313, because the condition on line 1307 was never false

1308 if not 0 <= spec < 54: 1308 ↛ 1309line 1308 didn't jump to line 1309, because the condition on line 1308 was never true

1309 raise PinInvalidPin('invalid GPIO port %d specified ' 

1310 '(range 0..53) ' % spec) 

1311 return spec 

1312 else: 

1313 if isinstance(spec, bytes): 

1314 spec = spec.decode('ascii') 

1315 spec = spec.upper() 

1316 if spec.isdigit(): 

1317 return self.to_gpio(int(spec)) 

1318 if spec.startswith('GPIO') and spec[4:].isdigit(): 

1319 return self.to_gpio(int(spec[4:])) 

1320 elif spec.startswith('BCM') and spec[3:].isdigit(): 

1321 return self.to_gpio(int(spec[3:])) 

1322 elif spec.startswith('WPI') and spec[3:].isdigit(): 

1323 main_head = 'P1' if 'P1' in self.headers else 'J8' 

1324 try: 

1325 return self.to_gpio({ 

1326 0: '%s:11' % main_head, 

1327 1: '%s:12' % main_head, 

1328 2: '%s:13' % main_head, 

1329 3: '%s:15' % main_head, 

1330 4: '%s:16' % main_head, 

1331 5: '%s:18' % main_head, 

1332 6: '%s:22' % main_head, 

1333 7: '%s:7' % main_head, 

1334 8: '%s:3' % main_head, 

1335 9: '%s:5' % main_head, 

1336 10: '%s:24' % main_head, 

1337 11: '%s:26' % main_head, 

1338 12: '%s:19' % main_head, 

1339 13: '%s:21' % main_head, 

1340 14: '%s:23' % main_head, 

1341 15: '%s:8' % main_head, 

1342 16: '%s:10' % main_head, 

1343 17: 'P5:3', 

1344 18: 'P5:4', 

1345 19: 'P5:5', 

1346 20: 'P5:6', 

1347 21: '%s:29' % main_head, 

1348 22: '%s:31' % main_head, 

1349 23: '%s:33' % main_head, 

1350 24: '%s:35' % main_head, 

1351 25: '%s:37' % main_head, 

1352 26: '%s:32' % main_head, 

1353 27: '%s:36' % main_head, 

1354 28: '%s:38' % main_head, 

1355 29: '%s:40' % main_head, 

1356 30: '%s:27' % main_head, 

1357 31: '%s:28' % main_head, 

1358 }[int(spec[3:])]) 

1359 except KeyError: 

1360 raise PinInvalidPin('%s is not a valid wiringPi pin' % spec) 

1361 elif ':' in spec: 

1362 header, pin = spec.split(':', 1) 

1363 if pin.isdigit(): 

1364 try: 

1365 header = self.headers[header] 

1366 except KeyError: 

1367 raise PinInvalidPin( 

1368 'there is no %s header on this Pi' % header) 

1369 try: 

1370 function = header.pins[int(pin)].function 

1371 except KeyError: 

1372 raise PinInvalidPin( 

1373 'no such pin %s on header %s' % (pin, header.name)) 

1374 if function.startswith('GPIO') and function[4:].isdigit(): 

1375 return self.to_gpio(int(function[4:])) 

1376 else: 

1377 raise PinInvalidPin('%s is not a GPIO pin' % spec) 

1378 elif spec.startswith('BOARD') and spec[5:].isdigit(): 

1379 main_head = ({'P1', 'J8', 'SODIMM'} & set(self.headers)).pop() 

1380 return self.to_gpio('%s:%s' % (main_head, spec[5:])) 

1381 raise PinInvalidPin('%s is not a valid pin spec' % spec) 

1382 

1383 def __repr__(self): 

1384 return '{cls}({fields})'.format( 

1385 cls=self.__class__.__name__, 

1386 fields=', '.join( 

1387 ( 

1388 '{name}=...' if name in ('headers', 'board') else 

1389 '{name}={value!r}').format(name=name, value=value) 

1390 for name, value in zip(self._fields, self) 

1391 ) 

1392 ) 

1393 

1394 def __format__(self, format_spec): 

1395 style, content = Style.from_style_content(format_spec) 

1396 if content == 'full': 

1397 return dedent("""\ 

1398 {self:{style} board} 

1399 

1400 {self:{style} specs} 

1401 

1402 {self:{style} headers}""" 

1403 ).format(self=self, style=style) 

1404 elif content == 'board': 

1405 kw = self._asdict() 

1406 kw.update({ 

1407 name: header 

1408 for name, header in self.headers.items() 

1409 }) 

1410 return self.board.format(style=style, **kw) 

1411 elif content == 'specs': 

1412 specs = self._asdict() 

1413 if specs['memory'] < 1024: 

1414 specs['memory_unit'] = "MB" 

1415 else: 

1416 specs['memory'] = int(specs['memory'] / 1024) 

1417 specs['memory_unit'] = "GB" 

1418 return dedent("""\ 

1419 {style:bold}Revision {style:reset}: {revision} 

1420 {style:bold}SoC {style:reset}: {soc} 

1421 {style:bold}RAM {style:reset}: {memory}{memory_unit} 

1422 {style:bold}Storage {style:reset}: {storage} 

1423 {style:bold}USB ports {style:reset}: {usb} (of which {usb3} USB3) 

1424 {style:bold}Ethernet ports {style:reset}: {ethernet} ({eth_speed}Mbps max. speed) 

1425 {style:bold}Wi-fi {style:reset}: {wifi} 

1426 {style:bold}Bluetooth {style:reset}: {bluetooth} 

1427 {style:bold}Camera ports (CSI) {style:reset}: {csi} 

1428 {style:bold}Display ports (DSI){style:reset}: {dsi}""" 

1429 ).format(style=style, **specs) 

1430 elif content == 'headers': 

1431 return '\n\n'.join( 

1432 dedent("""\ 

1433 {style:bold}{header.name}{style:reset}: 

1434 {header:{style} full}""" 

1435 ).format(header=header, style=style) 

1436 for header in sorted(self.headers.values(), key=attrgetter('name')) 

1437 ) 

1438 else: 

1439 raise ValueError('Invalid format specifier') 

1440 

1441 def pprint(self, color=None): 

1442 """ 

1443 Pretty-print a representation of the board along with header diagrams. 

1444 

1445 If *color* is :data:`None` (the default), the diagram will include ANSI 

1446 color codes if stdout is a color-capable terminal. Otherwise *color* 

1447 can be set to :data:`True` or :data:`False` to force color or monochrome 

1448 output. 

1449 """ 

1450 print('{0:{style} full}'.format(self, style=Style(color))) 

1451 

1452 

1453def pi_info(revision=None): 

1454 """ 

1455 Returns a :class:`PiBoardInfo` instance containing information about a 

1456 *revision* of the Raspberry Pi. 

1457 

1458 :param str revision: 

1459 The revision of the Pi to return information about. If this is omitted 

1460 or :data:`None` (the default), then the library will attempt to determine 

1461 the model of Pi it is running on and return information about that. 

1462 """ 

1463 if revision is None: 

1464 if Device.pin_factory is None: 

1465 Device.pin_factory = Device._default_pin_factory() 

1466 result = Device.pin_factory.pi_info 

1467 if result is None: 

1468 raise PinUnknownPi('The default pin_factory is not attached to a Pi') 

1469 else: 

1470 return result 

1471 else: 

1472 if isinstance(revision, bytes): 

1473 revision = revision.decode('ascii') 

1474 if isinstance(revision, str): 

1475 revision = int(revision, base=16) 

1476 else: 

1477 # be nice to people passing an int (or something numeric anyway) 

1478 revision = int(revision) 

1479 return PiBoardInfo.from_revision(revision)