mailto: blog -at- heyrick -dot- eu

Denver IR-135 serial port (better)

I didn't like the idea of having to open up the radio every time I wanted to do anything with the serial port, so I stripped down the device to make some different modifications.

Serial modifications
Serial modifications.

Rather than making changes to the casing, I simply passed the wires out under the bottom. So now I can plug into them without having to open up the radio. It's easy access to the serial port. And since I was there, I brought out the pin pair that switches the bootloader behaviour.

Serial connections at the back
Serial connections at the back.

 

This is what happened when I plugged in the power lead. The device booted, connected to WiFi, fetched the time, disconnected, and then displayed a big clock on the screen.

ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:4516
load:0x40078000,len:11260
load:0x40080400,len:5952
entry 0x400806a0
I (948) psram: This chip is ESP32-D0WD
I (958) psram: PSRAM is in 2T mode
I (959) spiram: Found 32MBit SPI RAM device
I (959) spiram: SPI RAM mode: flash 80m sram 80m
I (961) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (969) cpu_start: cpu freq: 240
I (973) cpu_start: Pro cpu up.
I (976) cpu_start: Application information:
I (981) cpu_start: Project name:     IR-135
I (986) cpu_start: ELF file SHA256:  3c935f1346673730...
I (992) cpu_start: ESP-IDF:          v3.3.5-dirty
I (997) cpu_start: Starting app cpu, entry point is 0x400818f8
I (0) cpu_start: App cpu up.
I (1485) spiram: SPI SRAM memory test OK
I (1535) heap_init: Initializing. RAM available for dynamic allocation:
I (1535) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (1537) heap_init: At 3FFB7468 len 00000B98 (2 KiB): DRAM
I (1543) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (1549) heap_init: At 3FFBDB5C len 00000004 (0 KiB): DRAM
I (1555) heap_init: At 3FFCC2D8 len 00013D28 (79 KiB): DRAM
I (1562) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1568) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1575) heap_init: At 4009E660 len 000019A0 (6 KiB): IRAM
I (1581) cpu_start: Pro cpu start user code
I (1586) spiram: Adding pool of 3431K of external SPI memory to heap allocator
I (40) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starti.
0:00:00.340 I (340) reportSystem: IR-135 20211110.1013, Running partition type 0 subtype 16 (offset 0x00020000)
0:00:01.436 I (1436) setBacklight: 60%
0:00:01.437 I (1437) I2S: DMA Malloc info, datalen=blocksize=4088, dma_buf_count=4
0:00:01.441 I (1441) I2S: APLL: Req RATE: 48000, real rate: 47999.961, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 12287990.000, SCLK: 1535998.750000, diva: 1, divb: 0

----------------------------- ESP Audio Platform -----------------------------
|                                                                            |
|                             Player_Version 0.97                            |
|                     Compile date: Apr 19 2021-11:28:06                     |
------------------------------------------------------------------------------
0:00:01.508 I (1508) BROADCAST: func:BroadcastInit, list=0x3ffd4fa0, que=0x0
0:00:01.509 I (1509) I2S_READER: CreateI2sStreamReader
0:00:01.511 I (1511) I2S_WRITER: CreateI2sStreamWriter
0:00:01.517 W (1517) SOFT_CODEC: CodecStop, have no codec instance,0x0
0:00:01.524 W (1524) SOFT_CODEC: CodecStop, have no codec instance,0x0
0:00:01.531 I (1531) MEDIA_CTRL: Media started, and wait, ctrl addr=3f8a6ab8
0:00:01.918 I (1918) READER: tskRead, waiting for a START_PLAY
0:00:01.920 I (1920) WebServer: SetCurrentIp ------> 127.0.0.1
0:00:01.924 I (1924) wifi:0:00:01.924 wifi driver task: 3ffde104, prio:23, stack:3072, core=00:00:01.924 
0:00:01.930 I (1930) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
0:00:01.941 I (1941) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
0:00:01.967 I (1967) wifi:0:00:01.967 wifi firmware version: dc300370:00:01.967 
0:00:01.967 I (1967) wifi:0:00:01.967 config NVS flash: enabled0:00:01.967 
0:00:01.970 I (1970) wifi:0:00:01.970 config nano formating: enabled0:00:01.970 
0:00:01.977 I (1977) wifi:0:00:01.978 Init data frame dynamic rx buffer num: 320:00:01.978 
0:00:01.985 I (1985) wifi:0:00:01.985 Init management frame dynamic rx buffer num: 320:00:01.985 
0:00:01.994 I (1994) wifi:0:00:01.994 Init management short buffer num: 320:00:01.994 
0:00:02.001 I (2001) wifi:0:00:02.001 Init static tx buffer num: 240:00:02.001 
0:00:02.009 I (2009) wifi:0:00:02.010 Init static rx buffer size: 22120:00:02.010 
0:00:02.016 I (2016) wifi:0:00:02.016 Init static rx buffer num: 80:00:02.016 
0:00:02.023 I (2023) wifi:0:00:02.023 Init dynamic rx buffer num: 320:00:02.023 
0:00:02.030 I (2030) wifi_init: rx ba win: 16
0:00:02.035 I (2035) wifi_init: tcpip mbox: 48
0:00:02.040 I (2040) wifi_init: udp mbox: 6
0:00:02.045 I (2045) wifi_init: tcp mbox: 46
0:00:02.050 I (2050) wifi_init: tcp tx win: 5840
0:00:02.055 I (2055) wifi_init: tcp rx win: 65535
0:00:02.060 I (2060) wifi_init: tcp mss: 1460
0:00:02.065 I (2065) wifi_init: LWIP IRAM OP enabled
0:00:02.071 I (2071) phy_init: phy_version 4660,0162888,Dec 23 2020
0:00:02.170 I (2170) wifi:0:00:02.171 mode : sta (78:21:84:xx:xx:xx)0:00:02.171 
0:00:02.172 I (2172) wifi:0:00:02.173 set country: cc=EU. schan=1 nchan=14 policy=0
0:00:02.174 
0:00:02.177 I (2177) wifi:0:00:02.177 Set ps type: 0
0:00:02.180 
0:00:02.184 I (2184) startKeyboard: type = 0, gradient = 53470, offset = 142, vref = 1114
0:00:02.186 I (2186) wifi:0:00:02.190 new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:10:00:02.190 
0:00:02.199 I (2199) wifi:0:00:02.200 state: init -> auth (b0)0:00:02.200 
0:00:02.208 I (2208) startKeyboard: type = 0, gradient = 15619, offset = 75, vref = 1114
0:00:02.209 I (2209) wifi:0:00:02.215 state: auth -> assoc (0)0:00:02.215 
0:00:02.226 I (2226) wifi:0:00:02.226 state: assoc -> run (10)0:00:02.226 
0:00:02.230 I (2230) configEqMode: EQ mode = 1
0:00:02.239 I (2239) setBacklight: 75%
0:00:02.483 I (2483) wifi:0:00:02.483 connected with VonetsRepeater, aid = 3, channel 1, BW20, bssid = 00:17:13:1c:xx:xxx:xx:xx.483 
0:00:02.484 I (2484) wifi:0:00:02.484 security type: 3, phy: bgn, rssi: -200:00:02.484 
0:00:02.497 I (2497) wifi:0:00:02.498 pm start, type: 0
0:00:02.498 
0:00:02.499 I (2499) NETWORK: SYSTEM_EVENT_STA_CONNECTED
0:00:02.552 I (2551) wifi:0:00:02.552 AP's beacon interval = 102400 us, DTIM period = 10:00:02.552 
0:00:03.586 I (3586) event: sta ip: 192.168.1.12, mask: 255.255.255.0, gw: 192.168.1.1
0:00:03.586 I (3586) NETWORK: SYSTEM_EVENT_STA_GOTIP
0:00:03.589 I (3589) NETWORK: NONE --> STA
0:00:03.595 I (3595) SKYTUNE: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:03.602 I (3602) READER: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:03.610 I (3610) UPNP: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:03.617 I (3617) WebServer: webServerEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:03.625 I (3625) WebServer: SetCurrentIp ------> 192.168.1.12
0:00:03.632 I (3632) UI: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:03.640 I (3640) NETWORK: getNetworkTime, ENTER
0:00:03.920 I (3920) SKYTUNE: Connecting to Skytune server... 0
0:00:04.161 I (4161) SKYTUNE: Skytune Server connected, 80
0:00:04.860 I (4860) SKYTUNE: Send logon message to server
0:00:05.153 I (5153) UI: DeviceEventNotify, got DEVICE_NOTIFY_TYPE_SKYTUNE_SERVICE_AUTO_DATA
0:00:05.367 I (5367) SKYTUNE: validateToken, tokenValidTime = 14400 seconds
0:00:05.367 I (5367) SKYTUNE: Check for update..., 0
0:00:05.575 I (5575) SKYTUNE: skytuneTask, Send bye to skytune
0:00:05.754 I (5754) PLAYER: stopPlay, ENTER
0:00:05.755 I (5755) PLAYER: stopPlay, LEAVE
0:00:05.884 I (5884) SKYTUNE: checkUpdateCallback, firmware up-to-date
0:00:06.095 E (6095) SKYTUNE: checkJobTimeout, Send dummy response, jobIndex=1
0:00:06.096 I (6096) SKYTUNE: checkDbCallback, timeout
0:00:06.098 W (6098) skytuneTask: Wait for resume...
0:00:06.197 I (6197) SKYTUNE: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.197 I (6197) READER: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.203 I (6203) UPNP: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.211 I (6211) WebServer: webServerEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.220 I (6219) UI: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.228 I (6228) NETWORK: wifiStop, ENTER
0:00:06.233 I (6233) wifi:0:00:06.233 state: run -> init (0)0:00:06.233 
0:00:06.239 I (6239) wifi:0:00:06.240 pm stop, total sleep time: 0 us / 3741357 us
0:00:06.246 
0:00:06.248 I (6248) wifi:0:00:06.248 new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:10:00:06.248 
0:00:06.258 I (6258) NETWORK: +JAP:DISCONNECTED,8
0:00:06.262 I (6262) NETWORK: STA --> NONE
0:00:06.265 I (6265) wifi:0:00:06.267 flush txq0:00:06.267 
0:00:06.272 I (6272) wifi:0:00:06.272 stop sw txq0:00:06.272 
0:00:06.278 I (6278) wifi:0:00:06.278 lmac stop hw txq0:00:06.278 
0:00:06.283 0:00:06.283 I (6283) SKYTUNE: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
I (6283) NETWORK: wifiStop, LEAVE
0:00:06.293 I (6293) READER: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.305 I (6305) UPNP: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.313 I (6313) WebServer: webServerEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.322 I (6322) UI: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_DISCONNECTED
0:00:06.331 I (6331) NETWORK: +JAP:DISCONNECTED, LEAVE
0:00:06.336 I (6336) NETWORK: +WIFI:STA_STOP
0:00:06.341 I (6341) wifi:0:00:06.341 Deinit lldesc rx mblock:80:00:06.341 
0:00:07.071 I (7071) setBacklight: 3%
0:00:07.072 I (7072) UI: setScreenState, NULL --> BIGCLOCK

 

I now press the Power button to switch out of standby and automatically begin playing WZBA (The Bay, Baltimore), the last played station.

0:00:18.676 I (18676) UI: key = 0x300
0:00:18.801 I (18801) UI: key = 0x8300
0:00:18.805 W (18805) skytuneTask: Resumed.
0:00:18.805 W (18805) Colman: TimeDiff = 13 Seconds, tickDiff=12710
0:00:18.806 W (18806) Colman: ************ Adj tokenStartTicks, 290d
0:00:18.807 I (18807) wifi:0:00:18.813 wifi driver task: 3ffbbb20, prio:23, stack:3072, core=00:00:18.813 
0:00:18.822 I (18822) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
0:00:18.833 I (18833) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
0:00:18.858 I (18858) wifi:0:00:18.858 wifi firmware version: dc300370:00:18.858 
0:00:18.858 I (18858) wifi:0:00:18.858 config NVS flash: enabled0:00:18.858 
0:00:18.861 I (18861) wifi:0:00:18.861 config nano formating: enabled0:00:18.861 
0:00:18.868 I (18868) wifi:0:00:18.868 Init data frame dynamic rx buffer num: 320:00:18.868 
0:00:18.876 I (18876) wifi:0:00:18.876 Init management frame dynamic rx buffer num: 320:00:18.876 
0:00:18.885 I (18885) wifi:0:00:18.885 Init management short buffer num: 320:00:18.885 
0:00:18.893 I (18893) wifi:0:00:18.893 Init static tx buffer num: 240:00:18.893 
0:00:18.901 I (18901) wifi:0:00:18.901 Init static rx buffer size: 22120:00:18.901 
0:00:18.907 I (18907) wifi:0:00:18.907 Init static rx buffer num: 80:00:18.907 
0:00:18.914 I (18914) wifi:0:00:18.914 Init dynamic rx buffer num: 320:00:18.914 
0:00:18.922 I (18922) wifi_init: rx ba win: 16
0:00:18.926 I (18926) wifi_init: tcpip mbox: 48
0:00:18.932 I (18932) wifi_init: udp mbox: 6
0:00:18.937 I (18937) wifi_init: tcp mbox: 46
0:00:18.942 I (18942) wifi_init: tcp tx win: 5840
0:00:18.947 I (18947) wifi_init: tcp rx win: 65535
0:00:18.952 I (18952) wifi_init: tcp mss: 1460
0:00:18.958 I (18958) wifi_init: LWIP IRAM OP enabled
0:00:18.964 I (18964) phy_init: phy_version 4660,0162888,Dec 23 2020
0:00:18.977 I (18977) wifi:0:00:18.977 mode : sta (78:21:84:xx:xx:xx)0:00:18.977 
0:00:18.979 I (18979) wifi:0:00:18.979 set country: cc=EU. schan=1 nchan=14 policy=0
0:00:18.985 
0:00:18.988 I (18988) wifi:0:00:18.988 Set ps type: 0
0:00:18.991 
0:00:18.992 I (18992) setBacklight: 75%
0:00:18.997 I (18997) wifi:0:00:18.997 new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:10:00:18.997 
0:00:18.999 I (18999) UI: setScreenState, BIGCLOCK --> MENU
0:00:19.006 I (19006) wifi:0:00:19.012 state: init -> auth (b0)0:00:19.012 
0:00:19.022 I (19022) wifi:0:00:19.022 state: auth -> assoc (0)0:00:19.022 
0:00:19.030 I (19030) wifi:0:00:19.031 state: assoc -> run (10)0:00:19.031 
0:00:19.219 I (19219) setResumeLastPlayTimer: Resume play after 3 seconds
0:00:19.276 I (19276) wifi:0:00:19.277 connected with VonetsRepeater, aid = 3, channel 1, BW20, bssid = 00:17:13:1c:xx:xxx:xx:xx.277 
0:00:19.278 I (19278) wifi:0:00:19.278 security type: 3, phy: bgn, rssi: -200:00:19.278 
0:00:19.291 I (19291) wifi:0:00:19.291 pm start, type: 0
0:00:19.291 
0:00:19.293 I (19293) NETWORK: SYSTEM_EVENT_STA_CONNECTED
0:00:19.345 I (19345) wifi:0:00:19.345 AP's beacon interval = 102400 us, DTIM period = 10:00:19.346 
0:00:20.085 I (20085) event: sta ip: 192.168.1.12, mask: 255.255.255.0, gw: 192.168.1.1
0:00:20.086 I (20086) NETWORK: SYSTEM_EVENT_STA_GOTIP
0:00:20.089 I (20089) NETWORK: NONE --> STA
0:00:20.096 I (20096) SKYTUNE: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:20.102 I (20102) READER: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:20.110 I (20110) UPNP: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:20.114 I (20114) SKYTUNE: Check for update..., 0
0:00:20.118 I (20118) WebServer: webServerEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:20.132 I (20132) WebServer: SetCurrentIp ------> 192.168.1.12
0:00:20.138 I (20138) UI: DeviceEventNotify, DEVICE_NOTIFY_NETWORK_GOT_IP
0:00:20.147 I (20147) NETWORK: getNetworkTime, ENTER
0:00:20.736 I (20736) SKYTUNE: checkUpdateCallback, firmware up-to-date
0:00:21.249 I (21249) SKYTUNE: checkDbCallback, dB up-to-date
0:00:22.877 I (22877) UI: bgTask, try to resume last song
0:00:22.879 I (22879) PLAYER: playSource, ENTER, myFav,13,14,"/spiffs/myFav.txt","100.7 The Bay - WZBA","1"
0:00:22.883 I (22883) setRampVolume: Target volume = 20, rate = 1
0:00:22.892 I (22892) PLAYER: playerPrepareNext, Enter, srcRef = myFav,13,14,"/spiffs/myFav.txt","100.7 The Bay - WZBA","1", stopCode = 0, desirePos = 0, numOfErr = 0
0:00:23.014 I (23014) PLAYER: stopPlay, ENTER
0:00:23.015 I (23015) PLAYER: stopPlay, LEAVE
0:00:23.016 0:00:23.016 I (23016) READER: setPlayerState, STOPPED -> CONNECTING_TO_NETWORK, stopCode = 0
0:00:23.016 I (23016) UI: setScreenState, MENU --> PLAYER
0:00:23.024 I (23024) READER: setPlayerState, CONNECTING_TO_NETWORK -> CONNECTING_TO_SERVER, stopCode = 0
0:00:23.040 I (23040) ec_handle_https_url: Playing: http://wzba.streamon.fm:8000/WZBA-48k.aac
I (23016) downloadAlbumTask: http://www.radioshaker.com/imagestation/12955.jpg
0:00:23.279 I (23279) PLAYER: playerPrepareNext, Leave
0:00:23.435 I (23435) HTTP_REQ: Code: 302
0:00:23.463 I (23463) ec_req_perform: Starting again (B)!
0:00:24.202 I (24202) downloadAlbumTask: download complete, size = 4901
0:00:24.203 E (24203) jpgDecode: jd_prepare() return 8
0:00:24.205 E (24205) downloadAlbumTask: image decode error, 8
0:00:24.211 I (24211) downloadAlbumTask: LEAVE
0:00:24.334 I (24334) icyData: br = 48
0:00:24.335 I (24335) icyData: Set start threshold to 30720 bytes
0:00:24.341 I (24341) icyData: genre = various
0:00:24.349 I (24349) icyData: name = 
0:00:24.353 I (24353) icyData: url = 
0:00:24.355 I (24355) icyData: description = Unspecified description
0:00:24.357 I (24357) icyData: pub = 0
0:00:24.720 I (24720) READER: setPlayerState, CONNECTING_TO_SERVER -> BUFFERING, stopCode = -1
0:00:24.908 I (24908) downloadAlbumTask: http://metadata.cdnstream1.com/?Album=...[clip stupidly long URL]...170x170bb.jpg
0:00:24.959 0:00:24.958 I (24959) setRampVolume: Target volume = 20, rate = 1
I (24958) READER: setPlayerState, BUFFERING -> PLAYING, stopCode = -1
0:00:24.982 I (24982) MEDIA_CTRL: MEDIA_CTRL_EVT_PLAY mode:0, src:0, AudioInfo: 0, 0, 0, 0, 0, 0
0:00:24.997 I (24997) PLAYER_HELPER: Stop helper AudioInfo: 0, 0, 0, 0, 0, 0
0:00:24.998 W (24998) SKYTUNE: skytuneReportStationStatus, OK=1, time=0
URI: raw://from.pcm/to.aac#i2s
0:00:25.014 W (25014) ELLIS_AUDIO: Initial download speed 1046Kbps
0:00:25.015 W (25015) SOFT_CODEC: CodecStop, have no codec instance,0x0
0:00:25.002 E (25002) connectHost: DNS lookup failed err=202, host=metadata.cdnstream1.com, port=80
0:00:25.028 I (25028) PLAYER_HELPER: Decoder only
0:00:25.043 I (25043) I2S_STREAM: I2sStream running, stream type 0, num 0
0:00:25.052 I (25052) MEDIA_HAL: Codec mode DECODE
0:00:25.057 I (25057) SOFT_CODEC: softdecoder task running & wait; type aac
0:00:25.064 I (25064) SOFT_CODEC: Before open:0 0, 0 0 0
0:00:25.111 I (25111) AACG_DECODER: new audio song
0:00:25.111 I (25111) AACG_DECODER: this audio is RAW AAC
0:00:25.177 I (25177) AACG_DECODER: I2S setup: sample_rate = 44100 : channels = 1
0:00:25.177 W (25177) SOFT_CODEC: metadata-set, 12 3fa0a584, 44100 1 16 5
0:00:25.182 I (25182) I2S_STREAM: STREAM_SETUP_RATE=44100, channel=1, bits=16, bps=88200,time=-1ms
0:00:25.194 I (25194) I2S: APLL: Req RATE: 44100, real rate: 44099.988, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11289597.000, SCLK: 1411199.625000, diva: 1, divb: 0
0:00:25.207 I (25207) AACG_DECODER: m4a sampleRate=44100, Channels=1, frameSize=2048
0:00:26.403 E (26403) connectHost: DNS lookup failed err=202, host=metadata.cdnstream1.com, port=80
0:00:27.410 E (27410) connectHost: DNS lookup failed err=202, host=metadata.cdnstream1.com, port=80
0:00:28.418 E (28418) connectHost: DNS lookup failed err=202, host=metadata.cdnstream1.com, port=80
0:00:28.858 W (28858) SKYTUNE: skytuneReportStationStatus, codec=AAC, sampleRate=44KHz, bitRate=48Kbps
0:00:29.431 E (29431) connectHost: DNS lookup failed err=202, host=metadata.cdnstream1.com, port=80
0:00:30.435 E (30435) downloadAlbumTask: Cannot open
0:00:30.435 I (30435) downloadAlbumTask: download complete, size = 0
0:00:30.437 E (30437) downloadAlbumTask: image decode error, -1
0:00:30.443 I (30443) downloadAlbumTask: LEAVE
0:00:38.839 I (38839) setBacklightFade: 3% in 2000mS

The first error above is because The Bay has no logo or album art. This is happening, as you can see from the above logging, because http://www.radioshaker.com/imagestation/12955.jpg redirects (HTTP 302) to an https version, but the radio doesn't seem to know to follow the redirect, so it just says the icon doesn't exist.
The remaining errors are because something (album art fetcher?) tries to connect to metadata.cdnstream1.com which is not a known host.

 

Now, using the IR app, I 'press' the buttons 1 and 0 to select the tenth station, Celtic Moon. This one does have a valid image.

0:01:57.368 I (117368) UI: key = 0x101
0:01:57.543 I (117543) UI: key = 0x8101
0:01:57.941 I (117941) UI: key = 0x100
0:01:58.118 I (118118) UI: key = 0x8100
0:02:01.526 I (121526) Colman: keyNumber, out string = 10
0:02:01.527 I (121527) setRampVolume: Target volume = 20, rate = 1
0:02:01.532 I (121532) PLAYER: playerPrepareNext, Enter, srcRef = myFav,13,14,"/spiffs/myFav.txt","100.7 The Bay - WZBA","1", stopCode = 0, desirePos = 0, numOfErr = 0
0:02:01.657 I (121657) PLAYER: stopPlay, ENTER
0:02:01.658 W (121658) PLAYER: Wait for reader stop...
0:02:02.014 I (122014) READER: setPlayerState, PLAYING -> STOPPING, stopCode = 5
0:02:02.017 W (122017) read_unchunked_block: User requested to stop
0:02:02.018 W (122018) kill_player: Wait for player stop...
0:02:02.244 I (122244) PLAYER_HELPER: Stop helper AudioInfo: 0, 0, 0, 0, 0, 0
0:02:02.244 I (122244) MEDIACTRL_TAG: Current Player Info: status:1,mode:3,errMsg:0,src:0, Func:rawStopByCtrl, Line:1146

0:02:02.244 E (122244) MPS_DECODER: CodecOutput: output aborted 2048
0:02:02.260 I (122260) MPS_DECODER: mp3 close
0:02:02.265 I (122265) SOFT_CODEC: softdecoder task deleted
0:02:02.344 I (122344) SOFT_CODEC: softdecoder stopped
0:02:02.344 W (122344) I2S_STREAM: I2sStream type 0 req stop, last time is 0
0:02:02.349 I (122349) I2S_WRITER: End of stream, read_write_len=4096, stream->_block_write=4096, stream type=0 (line: 211)
0:02:02.358 I (122358) MEDIA_HAL: Codec stop DECODE
0:02:02.365 I (122365) I2S_STREAM: deleted stream type=0, outSize=0
0:02:02.374 I (122374) I2S_STREAM: I2sStream type 0 stopped
0:02:02.377 I (122377) MEDIA_CTRL: MEDIA_CTRL_EVT_STOP,mode:0 resume: 1
0:02:02.384 W (122384) PLAYER_HELPER: Recover Status(455), status:0, mode:0, errMsg:0, mediaSrc:0
0:02:02.394 I (122394) PLAYER_HELPER: Recover Position(443), codecPos:0 skipData:0
0:02:02.402 I (122402) MEDIACTRL_TAG: Current Player Info: status:0,mode:0,errMsg:0,src:0, Func:rawStopByCtrl, Line:1146

0:02:02.403 0:02:02.415 I (122403) PLAYER_HELPER: Stop helper AudioInfo: 0, 0, 0, 0, 0, 0
W (122415) decodeRadioTask: LEAVE
0:02:02.424 I (122424) MEDIA_CTRL: MEDIA_CTRL_EVT_STOP,mode:0 resume: 1
0:02:02.427 W (122427) kill_player: Wait for player stop...END
0:02:02.435 W (122435) PLAYER_HELPER: Recover Status(455), status:0, mode:0, errMsg:0, mediaSrc:0
0:02:02.443 W (122443) ec_handle_https_url: Exit
0:02:02.451 I (122451) PLAYER_HELPER: Recover Position(443), codecPos:0 skipData:0
0:02:02.456 0:02:02.456 I (122456) READER: setPlayerState, STOPPING -> STOPPED, stopCode = 5
W (122456) PLAYER: Wait for reader stop...End
0:02:02.473 I (122473) READER: tskRead, waiting for a START_PLAY
0:02:02.478 I (122478) PLAYER: stopPlay, LEAVE
0:02:02.491 I (122491) downloadAlbumTask: https://cdn-radiotime-logos.tunein.com/s261708q.png
0:02:02.650 I (122650) READER: setPlayerState, STOPPED -> CONNECTING_TO_NETWORK, stopCode = 0
0:02:02.651 I (122651) READER: setPlayerState, CONNECTING_TO_NETWORK -> CONNECTING_TO_SERVER, stopCode = 0
0:02:02.659 I (122659) ec_handle_https_url: Playing: http://51.161.115.200:8096/listen.pls?sid=1&t=.m3u
0:02:03.152 I (123152) PLAYER: playerPrepareNext, Leave
0:02:03.344 I (123344) icyData: notice1 = <BR>This stream requires <a href="http://www.winamp.com">Winamp</a><BR>
0:02:03.346 I (123346) icyData: notice2 = Shoutcast DNAS/posix(linux x64) v2.6.1.777<BR>
0:02:03.362 I (123362) icyData: name = Celtic Moon
0:02:03.364 I (123364) icyData: genre = Celtic
0:02:03.366 I (123366) icyData: br = 128
0:02:03.369 I (123369) icyData: Set start threshold to 81920 bytes
0:02:03.376 I (123376) icyData: sr = 44100
0:02:03.381 I (123381) icyData: url = https://www.celticmusicradio.com
0:02:03.388 I (123388) icyData: pub = 1
0:02:03.402 I (123402) READER: setPlayerState, CONNECTING_TO_SERVER -> BUFFERING, stopCode = -1
0:02:03.856 I (123856) tryDecodeType: MP3 detected
0:02:03.856 I (123856) READER: setPlayerState, BUFFERING -> PLAYING, stopCode = -1
0:02:03.857 I (123857) setRampVolume: Target volume = 20, rate = 1
0:02:03.872 I (123872) MEDIA_CTRL: MEDIA_CTRL_EVT_PLAY mode:0, src:0, AudioInfo: 0, 0, 0, 0, 0, 0
0:02:03.872 W (123872) SKYTUNE: skytuneReportStationStatus, OK=1, time=0
0:02:03.876 I (123876) PLAYER_HELPER: Stop helper AudioInfo: 0, 0, 0, 0, 0, 0
0:02:03.887 URI: raw://from.pcm/to.mp3#i2s
W (123887) ELLIS_AUDIO: Initial download speed 1426Kbps
0:02:03.895 I (123895) PLAYER_HELPER: Decoder only
0:02:03.906 I (123906) I2S_STREAM: I2sStream running, stream type 0, num 0
0:02:03.913 I (123913) MEDIA_HAL: Codec mode DECODE
0:02:03.919 I (123919) SOFT_CODEC: softdecoder task running & wait; type mp3
0:02:03.926 I (123926) SOFT_CODEC: Before open:0 0, 0 0 0
0:02:03.932 I (123932) MPS_DECODER: mp3 open
0:02:03.945 I (123945) MPS_DECODER: I2S setup: sample_rate = 44100 : channels = 2, bitRate 128
0:02:03.947 W (123947) SOFT_CODEC: metadata-set, 0 0, 44100 2 16 0
0:02:03.954 I (123954) I2S_STREAM: STREAM_SETUP_RATE=44100, channel=2, bits=16, bps=176400,time=0ms
0:02:03.966 I (123966) I2S: APLL: Req RATE: 44100, real rate: 44099.988, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11289597.000, SCLK: 1411199.625000, diva: 1, divb: 0
0:02:04.900 I (124900) downloadAlbumTask: download complete, size = 34338
0:02:05.266 I (125266) downloadAlbumTask: LEAVE
0:02:07.853 W (127853) SKYTUNE: skytuneReportStationStatus, codec=MP3, sampleRate=44KHz, bitRate=128Kbps
0:02:17.828 I (137828) setBacklightFade: 3% in 2000mS

 

Denver IR-135 firmware fiddling

Now to connect the serial port fully (both Tx and Rx), and place a link between the other two wires to pull the pin low to signal to the bootloader to enter programming mode.

Serial connections at the back
Serial connections at the back.

When this was done, booting up the radio output a different message, a shorter one that indicated that it was waiting for a firmware upload.

On my PC, I went into the directory within the Arduino environment where esptool.py was located (for me, this was C:\arduino-1.8.8\portable\packages\esp32\tools\esptool_py\2.6.1).

I then entered the following at the command line, but didn't press Enter:

c:\python27\python esptool.py -p COM9 -b 921600 read_flash 0x0 0x1000000 radioflash.bin

I plugged in the power lead on the radio, and then pressed Enter.

If the power lead is not plugged in, you'd have to hold down the power button for the entire time, as the bootloader doesn't latch the "on" signal, it's the firmware that does this, and in bootloader mode, the firmware isn't running.

Then this happened:

esptool.py v2.8-dev
Serial port COM9
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 3)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme
None
Crystal is 40MHz
MAC: xx:xx:xx:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
16777216 (100 %)
Read 16777216 bytes at 0x0 in 287.4 seconds (467.0 kbit/s)...
Hard resetting via RTS pin...

Note the time, 287 seconds, or just a shade under five minutes.

 

I'm not going to upload a dump of the flash, as SPIFFS has splattered information all over the place in order to implement wear levelling on the flash. That information is my chosen favourite stations, and WiFi access points and passwords. Thanks, but I'd rather not publicise that.

It looks like the first around 26K is the bootloader. It's a modified version as it contains ANSI colours.

Following this, a number of embedded keys. I'm not sure what this is, it's laid out like this:

[20:21:xx:xx:xx:xx]
LinkKeyType = 4
PinLength = 16
LinkKey = 99e3798efxxxxxxxxxxxxxxxxxxxxdad8f
SCSupport = 00

[Adapter]
LE_LOCAL_KEY_IRK = b9042xxxxxxxxxxxxxxxxxxxx908524c
LE_LOCAL_KEY_IR = 6c4b35xxxxxxxxxxxxxxxxxxxx715d76
LE_LOCAL_KEY_DHK = 8948c7xxxxxxxxxxxxxxxxxxxx77f974
LE_LOCAL_KEY_ER = 67ff527xxxxxxxxxxxxxxxxxxxx475b4

It looks like it may try to contact one of machine13.aldtech.com, iradio.skytune.net, or *machine11.aldtech.com (does the * mean preferred?).

Other content look like it may be keys for settings. Things like PLAYMODE, BUFTIME, VOLUME, LASTPLAYED.

All of this is repeated many many times. I'm guessing when settings are to be saved, the flash filing system makes another copy rather than overwriting anything. A bit like how Flash on the Psion 3(a) worked?

At 128K into the dump, it looks like the firmware begins. IR-135, v3.3.5-dirty are in the first few lines. After some code is a pile of messages for all of the supported languages. Interesting messages are CD player, USB, TF card, DAB radio, Storage, FM radio, AUX-in, My name setup, Bass boost, LAN network, Line out gain, Cooking timer, and various messages related to those (like "Door open" for the CD player).

I'm guessing there are numerous devices based around an ESP32 device, which is why the firmware has all this stuff in it. I don't know if it's just a generic list of messages or if there is actually code for handling a CD player built in. Certainly, there is no hardware provision for a CD player (or any of the other stuff, come to think of it!).

Messages imply support for M4A, wav, AAC, FLAC, OGG, and MP3. But, yeah, streaming M4A from the network went rather wrong. I ought to try it again with serial connected to see why it panics and resets.

There's a TS parser, so this is how it can play BBC. ☺

The player version, as we've seen, identifies itself as v0.97 released on 19th April 2021.

This is a lie. There's a Polish site with a copy of the firmware of a MIR-260 device based around the same sort of hardware (registration needed for download). It identifies as 0.97 30th March 2020.

It is different in numerous ways. On my device, a lot of the built-in URLs end with .php (this is crap, it's just a string). More interestingly, it looks like there is no built in list of countries and/or genres. I guess the list is built dynamically by downloading from SkyTune's site. Perhaps an error in the parser is why it is providing a broken list?

There's no obvious sequence sent to the SkyTune server, so it won't be possible to see what's going on there without finding some way of intercepting the communications and hoping it's not https!

The firmware appears to end at around 3¼MB.
There's nothing (all bytes 255) until 12MB, at which point it looks like a dump of the raw data for managing the favourites and last played lists. And, of course, many multiple copies.

Still, I can see the stream URLs. The radio doesn't look them up each time, it remembers favourites. So...

  • iRadio,"BBC Radio 6 Music","http://open.live.bbc.co.uk/mediaselector/6/redir/version/2.0/mediaset/audio-syndication-low/proto/http/transferformat/hls/vpid/bbc_6music"
  • myFav,"Rock Antenne Symphonic Rock Webradio","http://s5-webradio.rockantenne.de/symphonic-rock/st
  • myFav,"Alouette","https://alouette-niort.ice.infomaniak.ch/alouette-niort-128.mp3|http://www.aldtech.com/station_icon/67731.png"
  • myFav,"100.7 The Bay - WZBA","http://wzba.streamon.fm:8000/WZBA-48k.aac
If there's a '|', it's the stream URL on the left and the logo URL on the right.

Multiple copies, end by 12¾MB into the dump. From then until the 16MB end, there's nothing.

 

How to find a serial port

I received an email asking how to locate a serial port on a device such as this.

If you see a space near a microcontroller with three or four pins in a row, there's a good chance that it is a serial port.
If there are more pins then it may be SPI or JTAG or something else.

So we're only looking for three or four in a row.

Is this a serial port?
Is this a serial port?

You will need two things. You'll need a multimeter in continuity mode, and you'll need an oscilloscope.

With the device turned off, locate anything connected to the ground plane and attach a multimeter probe to it. Then touch each of the pins of your suspected serial port until the multimeter beeps.
This is the 0v/Gnd pin.

If you have four pins, then there's a pretty good chance that one is Vcc, which these days is usually 3.3v. So find something that is liable to be connected to the power rail. In the above photo, the supply pin to the infra red receiver (top right) would be at 3.3V. There was no need for me to probe which pin was the power pin because I could see the track running directly to it. Otherwise, you should touch a probe to whatever you believe is at Vcc and then probe each of the remaining pins to see which one beeps.

Note: Do not make assumptions based upon "this pin is connected to a big flat area on the board". Yes, there's a pretty good chance that this is indeed the ground plane, but on multilayer boards this may not necessarily be the case. Always probe from known points.

For two remaining pins, see if you can trace the circuit back to the microcontroller. Don't worry if you see resistors to ground or +v. These are just to pull down/up the signal, so it rests at a known state when not being specifically driven.
If this is possible, you can look up the microcontroller pins on the datasheet.
Don't use your multimeter to probe the pins, you might have to pass through filtering and such so there won't necessarily be direct continuity.

Now, hook up your oscilloscope with the ground connection to the 0v/Gnd pin of the serial port, or anything else that is at board ground. Note that on some audio devices, "audio ground" is not the same as digital/circuit ground, so you may get really weird results if you try clipping onto, say, the ground pin of the hackphone jack socket.

Turn the device on.

Set your oscilloscope to 2V/div, and around the 50µS timebase. Now probe the two remaining pins. One will be at Vcc, which is likely the output pin (floating at Vcc is an idle situation). This pin will be the serial output. Or, if you're lucky, it'll be outputting data. Two pictures below is an example.

The other pin may be floating at Vcc, or it may seem to have a some sort of regular pulsing on it. Here's a photo of the serial input of my ESP32 based radio.

Unexpected serial input behaviour
Unexpected serial input behaviour.

Remember, when a serial line is connected, this signal will be pulled high until data is being sent, so this odd behaviour may be some sort of way of detecting if a serial input is actually connected.

Now to confirm that the serial output is indeed an output, you'll want to adjust your settings so the trace better fills the screen. This will be either the 1V/div or 0.5V/div depending on your 'scope (the earlier 2V/div was just in case Vcc was higher than the usual 3.3V).
Most microcontroller serial ports, these days, work at 115,200bps. So select the 50µS/div timebase and do something that is liable to generate serial output (if pressing buttons doesn't show anything, try turning the device off and back on).

You'll probably see something like this.

Serial data at 50us/div
Serial data at 50µS/div.

Now to determine the serial speed. Well, as I said microcontrollers these days tend to run at 115,200bps.
How to make sense of this on an oscilloscope? It's easy. Divide one second by the bit rate.

1 ÷ 115200 is 0.00000868055 (or 8.68055556E-6 if you use BASIC!).

Look how many digits are between the decimal point and the first digit.

     0.00000868055
       123456
           /|\
            |

  1 = Decisecond
  2 = Centisecond
  3 = Millisecond
  4 = -
  5 = -
  6 = Microsecond
  7 = -
  8 = -
  9 = Nanosecond

So, from this, we can see that every bit takes eight microseconds. So if you switch your oscilloscope to a 10µS timebase, then you should see the trace changes just slightly less than the width of each square.

Serial data at 10us/div
Serial data at 10µS/div.

If this is correct, then your serial data rate is, indeed, 115,200bps.

Older equipment may run at 19,200bps. This is 0.000052 which is around 50µS per bit.

You'll now know how your serial port is wired, and what speed it runs at. So it's just a matter of connecting the output to the Rx pin of your TTL serial device, and 0v/Gnd to the 0v/Gnd of your TTL serial device (connecting your Tx to serial input is optional if you don't plan to send data).

IMPORTANT: Never EVER hook a microcontroller's TTL serial port to the 9 pin serial port on the back of a computer. RS232 and the like use a signalling that is +/- anything between 6V to 20V, so it's perfectly possible to get a voltage swing between -20V and +20V. A pin that's expecting 3.3V will not cope with that, and it's a high enough voltage that you may fry the entire chip, not just the serial input.

It is recommended that you purchase a USB to serial interface that has a switchable 5V or 3.3V logic level, as you shouldn't try pushing 5V into a 3.3V input.

This is the serial interface I'm using. Cheap and cheerful on Amazon.

USB to serial interface
USB to serial interface.

 

I didn't spend a weekend farting around with this

I've been tidying up the wood from the cut-down tree.
Tidying the wood detritus
Tidying the wood detritus.

Outstanding jobs are to get the chainsaw to chop the big log (just to the right of the stump) into manageable sections. Then to go and tidy up all the broken bits of wood lying around.
But all the big bits? They've been cleared.

The branches have been put on the wood graveyard.

The thicker bits I've put aside.

Keeping the good bits
Keeping the good bits.

I also washed my car, and note that my front left headlight isn't working. A problem with the switch (it stopped working, then started again, so...?) or a blown bulb? Kind of wish the mechanic changed the bulbs when I asked him to...

Also, of course, walked the furry. Or, rather, had to deal with her climbing on a roof and getting stuck. Again.

Now, semolina with raspberry jam and Netflix. ☺

 

 

Your comments:

Please note that while I check this page every so often, I am not able to control what users write; therefore I disclaim all liability for unpleasant and/or infringing and/or defamatory material. Undesired content will be removed as soon as it is noticed. By leaving a comment, you agree not to post material that is illegal or in bad taste, and you should be aware that the time and your IP address are both recorded, should it be necessary to find out who you are. Oh, and don't bother trying to inline HTML. I'm not that stupid! ☺ ADDING COMMENTS DOES NOT WORK IF READING TRANSLATED VERSIONS.
 
You can now follow comment additions with the comment RSS feed. This is distinct from the b.log RSS feed, so you can subscribe to one or both as you wish.

Berry, 11th December 2023, 11:43
Hi Rick, 
 
excellent work on hacking the internet radio device and getting to the serial output and the firmware dump. Thank you for sharing it! 
 
I'm investigating a similar device branded as "Ocean Digital" (www.oceandigitalshop.com), which is undoubtedly made by the same OEM factory, display output looks the same as on your screenshots. Btw. Ocean Digital also has a model with CD player, hence the text in the firmware. 
Can you share the Polish website which you have mentioned, with other firmware dump?
Berry, 11th December 2023, 11:49
P.S. I'm an experienced programmer and IT guy, but very new to ESP32 programming. Browsing your blog I see that you have experience writing the ESP32 code. How much work would it be to write an open-source firmware for this (type) of net radio hardware? 
 
I think many would be interested for an community-driven open-source firmware. Similar as several projects for firmware compatible with many routers...

Add a comment (v0.11) [help?] . . . try the comment feed!
Your name
Your email (optional)
Validation Are you real? Please type 47538 backwards.
Your comment
French flagSpanish flagJapanese flag
Calendar
«   February 2023   »
MonTueWedThuFriSatSun
  123
678912
141516
21232526
2728     

(Felicity? Marte? Find out!)

Last 5 entries

List all b.log entries

Return to the site index

Geekery

Search

Search Rick's b.log!

PS: Don't try to be clever.
It's a simple substring match.

Etc...

Last read at 16:12 on 2024/04/26.

QR code


Valid HTML 4.01 Transitional
Valid CSS
Valid RSS 2.0

 

© 2023 Rick Murray
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted.
RIPA notice: No consent is given for interception of page transmission.

 

Have you noticed the watermarks on pictures?
Next entry - 2023/02/20
Return to top of page