音樂播放器之 CD 轉成 mp3《三》下‧上

在進入『  PiTFT 3.5″ 觸控螢幕』之前,讓我們先補充一下,如何在樹莓派上,用命令列來播放 CD ︰

mplayer cdda:// 【default /dev/cdrom】
mplayer -cdrom-device /dev/sr0 cdda://

。俗話說︰書到用時方恨少。其實這是實務上常有的狀況,近年來更由於科技飛速變遷倍增壓力。如果真的有『藤子.F.不二雄』所說的《 小叮噹的記憶土司!!》果然幫的上忙嗎?縱使『學海無涯』只是顯現《如何閱讀□○??》的重要性。假使一個人能夠『固守』所學之『』,將它『連接』成『』,『編織』為『』,『貫串』一『』,就算『學網恢恢』也該是『疏而不漏』的吧!!

當我們『閱讀』他人的『文章』,也許會發現『胡適之』先生的『讀書四到』之好處,於此引用他講的『手到』︰

手到的功用。我常說:發表是吸收智識和思想的絕妙方法吸收進來的智識思想,無論是看書來的,或是聽講來的,都只是模糊零碎,都算不得我們自己的東西。自己必須做一番手腳,或做提要,或做說明,或做討論,自己重新組織過,申敘過,用自己的語言記述過,–那種智識思想方才可算是你自己的了。

。如果將此用於『樹莓派』的『學習』上,就是親身『動手做』 Do It Yourself ,如是漸次建立了自己的『思想』與『作法』。當『聽聞』各種『議論』── 比方說udevadm freezes board》── 時,我們可以『驗證』與『判斷』【 udevadm info -a -n /dev/sda 】是否會發生那篇文章所說的事?假使真的會,那麼這個『音樂播放器』上的『程式設計』就必須小心的避開那個可能引發『當機』的 Bug。其實那篇論壇上的癹文 Post 所說之事,曾經發生過 ── 見《Oops in dwc_otg_dump_spram running udevadm #21》── ,就作者當時所『』之記憶︰只要在『 udevadm 』指令上使用『 – -attribute-walk 』選項,就會當機,與使用的 kernel 版本有關。之後『樹莓派基金會』為了能更好的服務『使用者』,於是決定發行『官方版』,此時就與『 raspbian.org 』的發行分開了。或許正因那癹文者不知道過去的一段歷史所導致的吧!底下列出在『原型機』上使用『大拇哥』的命令結果給讀者參考︰

udevadm info -a -n /dev/sda

Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.

looking at device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0/host1/target1:0:0/1:0:0:0/block/sda’:
KERNEL==”sda”
SUBSYSTEM==”block”
DRIVER==””
ATTR{ro}==”0″
ATTR{size}==”15663104″
ATTR{stat}==” 170 2 1376 570 0 0 0 0 0 570 570″
ATTR{range}==”16″
ATTR{discard_alignment}==”0″
ATTR{events}==”media_change”
ATTR{ext_range}==”256″
ATTR{events_poll_msecs}==”-1″
ATTR{alignment_offset}==”0″
ATTR{inflight}==” 0 0″
ATTR{removable}==”1″
ATTR{capability}==”51″
ATTR{events_async}==””

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0/host1/target1:0:0/1:0:0:0’:
KERNELS==”1:0:0:0″
SUBSYSTEMS==”scsi”
DRIVERS==”sd”
ATTRS{rev}==”1.00″
ATTRS{type}==”0″
ATTRS{scsi_level}==”3″
ATTRS{model}==”DataTraveler G2 “
ATTRS{state}==”running”
ATTRS{queue_type}==”none”
ATTRS{iodone_cnt}==”0xd2″
ATTRS{iorequest_cnt}==”0xd2″
ATTRS{evt_capacity_change_reported}==”0″
ATTRS{timeout}==”30″
ATTRS{evt_media_change}==”0″
ATTRS{max_sectors}==”240″
ATTRS{ioerr_cnt}==”0x1″
ATTRS{queue_depth}==”1″
ATTRS{vendor}==”Kingston”
ATTRS{evt_soft_threshold_reached}==”0″
ATTRS{device_blocked}==”0″
ATTRS{evt_mode_parameter_change_reported}==”0″
ATTRS{evt_lun_change_reported}==”0″
ATTRS{evt_inquiry_change_reported}==”0″
ATTRS{iocounterbits}==”32″
ATTRS{eh_timeout}==”10″

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0/host1/target1:0:0’:
KERNELS==”target1:0:0″
SUBSYSTEMS==”scsi”
DRIVERS==””

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0/host1’:
KERNELS==”host1″
SUBSYSTEMS==”scsi”
DRIVERS==””

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0’:
KERNELS==”1-1.2.3:1.0″
SUBSYSTEMS==”usb”
DRIVERS==”usb-storage”
ATTRS{bInterfaceClass}==”08″
ATTRS{bInterfaceSubClass}==”06″
ATTRS{bInterfaceProtocol}==”50″
ATTRS{bNumEndpoints}==”02″
ATTRS{supports_autosuspend}==”1″
ATTRS{bAlternateSetting}==” 0″
ATTRS{bInterfaceNumber}==”00″

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.3’:
KERNELS==”1-1.2.3″
SUBSYSTEMS==”usb”
DRIVERS==”usb”
ATTRS{bDeviceSubClass}==”00″
ATTRS{bDeviceProtocol}==”00″
ATTRS{devpath}==”1.2.3″
ATTRS{idVendor}==”0951″
ATTRS{speed}==”480″
ATTRS{bNumInterfaces}==” 1″
ATTRS{bConfigurationValue}==”1″
ATTRS{bMaxPacketSize0}==”64″
ATTRS{busnum}==”1″
ATTRS{devnum}==”8″
ATTRS{configuration}==””
ATTRS{bMaxPower}==”200mA”
ATTRS{authorized}==”1″
ATTRS{bmAttributes}==”80″
ATTRS{bNumConfigurations}==”1″
ATTRS{maxchild}==”0″
ATTRS{bcdDevice}==”13c6″
ATTRS{avoid_reset_quirk}==”0″
ATTRS{quirks}==”0x0″
ATTRS{serial}==”00137299805EA9B0B62404CF”
ATTRS{version}==” 2.00″
ATTRS{urbnum}==”630″
ATTRS{ltm_capable}==”no”
ATTRS{manufacturer}==”Kingston”
ATTRS{removable}==”unknown”
ATTRS{idProduct}==”1624″
ATTRS{bDeviceClass}==”00″
ATTRS{product}==”DataTraveler G2″

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1/1-1.2’:
KERNELS==”1-1.2″
SUBSYSTEMS==”usb”
DRIVERS==”usb”
ATTRS{bDeviceSubClass}==”00″
ATTRS{bDeviceProtocol}==”02″
ATTRS{devpath}==”1.2″
ATTRS{idVendor}==”1a40″
ATTRS{speed}==”480″
ATTRS{bNumInterfaces}==” 1″
ATTRS{bConfigurationValue}==”1″
ATTRS{bMaxPacketSize0}==”64″
ATTRS{busnum}==”1″
ATTRS{devnum}==”4″
ATTRS{configuration}==””
ATTRS{bMaxPower}==”100mA”
ATTRS{authorized}==”1″
ATTRS{bmAttributes}==”e0″
ATTRS{bNumConfigurations}==”1″
ATTRS{maxchild}==”7″
ATTRS{bcdDevice}==”0100″
ATTRS{avoid_reset_quirk}==”0″
ATTRS{quirks}==”0x0″
ATTRS{version}==” 2.00″
ATTRS{urbnum}==”64″
ATTRS{ltm_capable}==”no”
ATTRS{removable}==”removable”
ATTRS{idProduct}==”0201″
ATTRS{bDeviceClass}==”09″
ATTRS{product}==”USB 2.0 Hub [MTT]”

looking at parent device ‘/devices/platform/bcm2708_usb/usb1/1-1’:
KERNELS==”1-1″
SUBSYSTEMS==”usb”
DRIVERS==”usb”
ATTRS{bDeviceSubClass}==”00″
ATTRS{bDeviceProtocol}==”02″
ATTRS{devpath}==”1″
ATTRS{idVendor}==”0424″
ATTRS{speed}==”480″
ATTRS{bNumInterfaces}==” 1″
ATTRS{bConfigurationValue}==”1″
ATTRS{bMaxPacketSize0}==”64″
ATTRS{busnum}==”1″
ATTRS{devnum}==”2″
ATTRS{configuration}==””
ATTRS{bMaxPower}==”2mA”
ATTRS{authorized}==”1″
ATTRS{bmAttributes}==”e0″
ATTRS{bNumConfigurations}==”1″
ATTRS{maxchild}==”5″
ATTRS{bcdDevice}==”0200″
ATTRS{avoid_reset_quirk}==”0″
ATTRS{quirks}==”0x0″
ATTRS{version}==” 2.00″
ATTRS{urbnum}==”51″
ATTRS{ltm_capable}==”no”
ATTRS{removable}==”unknown”
ATTRS{idProduct}==”9514″
ATTRS{bDeviceClass}==”09″

looking at parent device ‘/devices/platform/bcm2708_usb/usb1’:
KERNELS==”usb1″
SUBSYSTEMS==”usb”
DRIVERS==”usb”
ATTRS{bDeviceSubClass}==”00″
ATTRS{bDeviceProtocol}==”01″
ATTRS{devpath}==”0″
ATTRS{idVendor}==”1d6b”
ATTRS{speed}==”480″
ATTRS{bNumInterfaces}==” 1″
ATTRS{bConfigurationValue}==”1″
ATTRS{bMaxPacketSize0}==”64″
ATTRS{authorized_default}==”1″
ATTRS{busnum}==”1″
ATTRS{devnum}==”1″
ATTRS{configuration}==””
ATTRS{bMaxPower}==”0mA”
ATTRS{authorized}==”1″
ATTRS{bmAttributes}==”e0″
ATTRS{bNumConfigurations}==”1″
ATTRS{maxchild}==”1″
ATTRS{bcdDevice}==”0312″
ATTRS{avoid_reset_quirk}==”0″
ATTRS{quirks}==”0x0″
ATTRS{serial}==”bcm2708_usb”
ATTRS{version}==” 2.00″
ATTRS{urbnum}==”26″
ATTRS{ltm_capable}==”no”
ATTRS{manufacturer}==”Linux 3.12.26+ dwc_otg_hcd”
ATTRS{removable}==”unknown”
ATTRS{idProduct}==”0002″
ATTRS{bDeviceClass}==”09″
ATTRS{product}==”DWC OTG Controller”

looking at parent device ‘/devices/platform/bcm2708_usb’:
KERNELS==”bcm2708_usb”
SUBSYSTEMS==”platform”
DRIVERS==”dwc_otg”
ATTRS{hnp}==”HstNegScs = 0x0″
ATTRS{srp}==”SesReqScs = 0x1″
ATTRS{regvalue}==”invalid offset”
ATTRS{hsic_connect}==”HSIC Connect = 0x1″
ATTRS{guid}==”GUID = 0x2708a000″
ATTRS{mode}==”Mode = 0x1″
ATTRS{srpcapable}==”SRPCapable = 0x1″
ATTRS{regdump}==”Register Dump”
ATTRS{gpvndctl}==”GPVNDCTL = 0x00000000″
ATTRS{ggpio}==”GGPIO = 0x00000000″
ATTRS{hprt0}==”HPRT0 = 0x00001005″
ATTRS{wr_reg_test}==”Time to write GNPTXFSIZ reg 10000000 times: 420 msecs (42 jiffies)”
ATTRS{hcd_frrem}==”HCD Dump Frame Remaining”
ATTRS{mode_ch_tim_en}==”Mode Change Ready Timer Enable = 0x0″
ATTRS{gnptxfsiz}==”GNPTXFSIZ = 0x01000306″
ATTRS{remote_wakeup}==”Remote Wakeup Sig = 0 Enabled = 0 LPM Remote Wakeup = 0″
ATTRS{busconnected}==”Bus Connected = 0x1″
ATTRS{hcddump}==”HCD Dump”
ATTRS{gotgctl}==”GOTGCTL = 0x001c0001″
ATTRS{spramdump}==”SPRAM Dump”
ATTRS{grxfsiz}==”GRXFSIZ = 0x00000306″
ATTRS{gsnpsid}==”GSNPSID = 0x4f54280a”
ATTRS{gusbcfg}==”GUSBCFG = 0x00001700″
ATTRS{hptxfsiz}==”HPTXFSIZ = 0x02000406″
ATTRS{devspeed}==”Device Speed = 0x0″
ATTRS{fr_interval}==”Frame Interval = 0x1d4c”
ATTRS{rem_wakeup_pwrdn}==””
ATTRS{bussuspend}==”Bus Suspend = 0x0″
ATTRS{buspower}==”Bus Power = 0x1″
ATTRS{hnpcapable}==”HNPCapable = 0x1″
ATTRS{rd_reg_test}==”Time to read GNPTXFSIZ reg 10000000 times: 1440 msecs (144 jiffies)”
ATTRS{enumspeed}==”Device Enumeration Speed = 0x1″
ATTRS{inv_sel_hsic}==”Invert Select HSIC = 0x0″
ATTRS{regoffset}==”0xffffffff”

looking at parent device ‘/devices/platform’:
KERNELS==”platform”
SUBSYSTEMS==””
DRIVERS==””

 

350px-SPI_single_slave.svg
SPI bus: single master and single slave

400px-SPI_8-bit_circular_transfer.svg
A typical hardware setup

400px-SPI_timing_diagram2.svg
A timing diagram showing clock polarity and phase

bplus-gpio
B+ GPIO

序列週邊介面』 SPI Serial Peripheral Interface 是一種三或四線『同步式』序列資料之『鏈接』 link 電路,據聞,最早由 Motorola 公司所『命名』,功能適用於短距離、全雙工、單一『主控器』 master 的通訊系統。雖然說『樹莓派』上的 BCM2835 晶片有三個 SPI 控制器,然而 GPIO 擴張接腳上只有一個控制器,可以連接兩個 SPI 週邊。Adafruit 的『 PiTFT 3.5″觸控螢幕』就是使用 SPI 『匯流排』 Bus 的裝置,其一用於『螢幕輸出』,另一用於『觸控輸入』。這可以用『 dmesg | grep stmpe 』來確認。而且 Adafruit 的安裝程式創建了一個 udev 的規則『 /etc/udev/rules.d/95-stmpe.rules 』︰

SUBSYSTEM==”input”, ATTRS{name}==”stmpe-ts”, ENV{DEVNAME}==”*event*”, SYMLINK+=”input/touchscreen”

,將『觸控輸入』命名為『 touchscreen 』放在『/dev/input』的目錄下。或許因為 Adafruit 的『 PiTFT 3.5″觸控螢幕』已經使用了兩個 SPI 裝置,為了避免可能的『衝突』,所以當『驅動程式』 fbtft_device 載入時,它就將系統原始的『 spidev0.0 』以及『 spidev0.1 』裝置給刪除了︰

dmesg | grep spi

[ 5.743015] bcm2708_spi bcm2708_spi.0: master is unqueued, this is deprecated
[ 5.876934] bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)
[ 14.052342] fbtft_device: spidev spi0.0 500kHz 8 bits mode=0x00
[ 14.061006] fbtft_device: spidev spi0.1 500kHz 8 bits mode=0x00
[ 14.222481] fbtft_device: Deleting spi0.1 (spi0.1)
[ 14.236388] stmpe-spi spi0.1: stmpe610 detected, chip id: 0x811
[ 14.262495] fbtft_device: Deleting spi0.0 (spi0.0)
[ 14.309301] fbtft_device: stmpe610 spi0.1 500kHz 8 bits mode=0x00
[ 14.341123] fbtft_device: fb_hx8357d spi0.0 32000kHz 8 bits mode=0x00
[ 14.409289] input: stmpe-ts as /devices/platform/bcm2708_spi.0/spi_master/spi0/spi0.1/stmpe-ts.0/input/input2
[ 16.160748] graphics fb1: fb_hx8357d frame buffer, 480×320, 300 KiB video memory, 4 KiB DMA buffer memory, fps=20, spi0.0 at 32 MHz

,所以我們無法如網路上之一些文章所講的,用『 ls -la /dev/spi* 』方法來確定 SPI 裝置是否『存在』。雖然我們可以從『開機過程』和『登錄畫面』來確認『螢幕』工作正常,那麼我們要怎麽確認『觸控輸入』的問題呢?如果用『 cat /dev/input/touchscreen | hexdump 』︰

第一次觸控輸出
0000000 434d 549e d405 0002 0003 0000 0681 0000
0000010 434d 549e d405 0002 0003 0001 0821 0000
0000020 434d 549e d405 0002 0003 0018 0078 0000
0000030 434d 549e d405 0002 0001 014a 0001 0000
0000040 434d 549e d405 0002 0000 0000 0000 0000
0000050 434d 549e f805 0002 0003 0000 06e7 0000
0000060 434d 549e f805 0002 0003 0001 087e 0000
0000070 434d 549e f805 0002 0003 0018 0068 0000
0000080 434d 549e f805 0002 0000 0000 0000 0000
0000090 434d 549e 19d8 0003 0003 0000 06cb 0000
00000a0 434d 549e 19d8 0003 0003 0001 0883 0000
00000b0 434d 549e 19d8 0003 0003 0018 00a4 0000
00000c0 434d 549e 19d8 0003 0000 0000 0000 0000
00000d0 434d 549e 4733 0003 0003 0000 0673 0000
00000e0 434d 549e 4733 0003 0003 0001 085c 0000
00000f0 434d 549e 4733 0003 0003 0018 00c3 0000
0000100 434d 549e 4733 0003 0000 0000 0000 0000
0000110 434d 549e 6804 0003 0003 0000 068c 0000
0000120 434d 549e 6804 0003 0003 0001 0853 0000
0000130 434d 549e 6804 0003 0003 0018 00c5 0000
0000140 434d 549e 6804 0003 0000 0000 0000 0000
0000150 434d 549e 8937 0003 0003 0000 06f2 0000
0000160 434d 549e 8937 0003 0003 0001 0881 0000
0000170 434d 549e 8937 0003 0003 0018 0083 0000
0000180 434d 549e 8937 0003 0000 0000 0000 0000
0000190 434d 549e a9d4 0003 0003 0000 06f6 0000
00001a0 434d 549e a9d4 0003 0003 0001 087d 0000
00001b0 434d 549e a9d4 0003 0003 0018 0073 0000
00001c0 434d 549e a9d4 0003 0000 0000 0000 0000
00001d0 434d 549e 1528 0004 0003 0018 0000 0000
00001e0 434d 549e 1528 0004 0001 014a 0000 0000
00001f0 434d 549e 1528 0004 0000 0000 0000 0000
0000200 434d 549e 9e1a 0004 0003 0000 06a4 0000
0000210 434d 549e 9e1a 0004 0003 0001 0829 0000
0000220 434d 549e 9e1a 0004 0003 0018 004b 0000
0000230 434d 549e 9e1a 0004 0001 014a 0001 0000
0000240 434d 549e 9e1a 0004 0000 0000 0000 0000
0000250 434d 549e c49e 0004 0003 0000 0694 0000
0000260 434d 549e c49e 0004 0003 0018 0088 0000
0000270 434d 549e c49e 0004 0000 0000 0000 0000
0000280 434d 549e 234c 0005 0003 0018 0000 0000
0000290 434d 549e 234c 0005 0001 014a 0000 0000
00002a0 434d 549e 234c 0005 0000 0000 0000 0000

,這樣我們真能歸結『觸控』硬體是沒有問題的嗎??

 

─── 待續