TI FM Radio - Android Software/Hacking General [Developers Only]

Preface
Hi !
In my reading of various threads it's become apparent that there are MANY people who passionately
desire a "real FM radio" app. Not all of us live in data dense areas, or can afford the costs of
streaming audio. And not all of us have given up on RF broadcasts, either due to our tastes,
local available programming, lack of commercials or whatever. And many of us very much desire
the ability to transmit on the FM band for various reasons.
I want this thread to deal with TI FM radios on all devices that contain TI chips. My observation is that
there is a great deal of commonality in the TI chips supporting FM in the last 4-6 years.
I don't generally want to deal with the Broadcom FM chips here, but the audio routing issues will be similar.
I also WOULD like to create a list of devices containing the FM chips they use, so people can more quickly
determine their FM chip type.
To non-devs who want FM yesterday: Yes, I know. No need to post about it. I'll do my best to create some
kind of app ASAP, but first some fundamentals need to be figured out. I'd think and hope that others will also
be able to create FM radio apps from the info here and elsewhere.
This thread is in a developer forum, and as such it would be preferable to limit discussion to technical
aspects, preferrably by those who are developers or thereabouts in terms of technical skills. It's hard
work sometimes to slog through near 100 page threads such as the one for the Nexus One FM radio.
If you have simple questions, comments, requests, corrections or additions to this, please consider
PMing me directly and I'll do my best to incorporate that into the thread, giving acknowledgement
if you so desire.
That said, I've posted FM Receiver and FM Transmitter scripts below. If you feel you have a reasonable
capability to try these scripts on your device, please do, and report here or via PM on success or failure
if you might be among the first few to try these on your device/model.
I will try to keep these first posts updated with the latest information, so hopefully you won't need to post
questions about whether or not your device works by referring to the "Devices" post.
---------------------
Introduction
I've enabled the FM radio functions on my HTC Legend. It is also known to work on HTC Tattoo.
Scouring the web looking for the magic incantations to enable FM audio I'm finding myself overwhelmed with all the things I don't know.
Much of the information needed is kept under wraps by TI and their customers. To get TI's information requires signing an NDA,
and perhaps other legal documents. Signing such an NDA limits how much you can say publicly, and I'd prefer to not be under
such constraints. I'm not even sure if an NDA would be sufficient for a person not employed by TI or a TI customer.
Thus this thread, to share with you the information I've found, and to ask for your help in correcting it or adding to it.
If there is any similar thread on any site, that is TI specific, but not device model specific, please let me know.
I've seen and read through a number of mega-threads here and elsewhere that are device specific, but much of the information
contained therein is useful for all devices with TI FM chips.
The chips in question are usually named: WL1271, WL1273, WL1281 and WL1283. The first two have WF + BT + FM and the latter two add GPS.
TI also calls these WiLink or BlueLink 5.0, 6.0 and 7.0, as well as BRF6300, BRF6350 and BL6450.
TI also sells various evaluation boards carrying these chips, and some TI partners produce modules, sometimes with similar numbers.
AFAICT there is no FM functionality in some of the predecessor chips such as the WiLink 4.0 chips: BRF6100 (WL1251) & BRF6150 (WL1253).
Just so you better know my knowledge level:
- I'm new to Android, smartphones and post 1995 PDAs, although I've read some on these subjects over the years.
I'm diving straight in to learn as much as I can as quickly as I can. I'm not currently employed but hope to
transition myself to what appears to be the rapidly expanding Android world.
- I've worked in software development on "semi-embedded" Linux VOIP and security appliances since 1997, with a good bit
of low level kernel/driver stuff. Not much low level stuff recently, mostly daemons and command line utilities.
At home I've recently worked on a home Asterisk VOIP box and MythTv and XBMC based HTPCs. I also manage the 5 Ubuntu
PCs our family uses, as well as one lonely 5 year old HP WinXp tablet.
- My background in electronics and computing goes back to the mid 1970's with 8080 and SCMP. I designed and built a variety
of computer, electronics and even RF devices in those days, and can still wield a mean soldering pencil when needed.
-----------------------------------------------------------------------------------------------------------------------------------------------------
Here is some information about which chips being discussed here. Note that the terms BlueLink and WiLink can be somewhat confusing as some chips are both.
TI's Wireless Connectivity Solutions page:
http://focus.ti.com/general/docs/wt...lateId=6123&navigationId=12493&contentId=4637
Note at left that GPS (NaviLink), Bluetooth (BlueLink) and Wireless (WiLink) are represented.
FM radio seems to be the neglected "step child" that gets little mention or notice.
It's a small add-on feature that just happens to come along with Bluetooth sometimes, if at all.
Generally, the WiFi, BT, FM and GPS components in these multi-function chips tend to be independent of each other.
They can be powered up or down individually and usually have seperate control paths. They are called "IP"s, eg.
the WiFi IP or BT IP. I haven't yet determined what IP stands for, LOL.
FM is the exception though; it seems to piggyback on the BT IP. To power up FM you must first power up BT
(although some doc implied BT can then be powered down). FM has it's own I2C control path, but that is usually
not used, in favor of sharing the BT HCI interface.
Some docs I've read discourage the use of FM. Perhaps it can cause issues ?
Note that some of these chips may indicate support for Wireless-N, but that doesn't mean the device manufacturer
enabled it in their stack etc. It might be possible to enable N, perhaps with different Wireless firmware or init
scripts. While an interesting prospect, despite the expectation of vastly increased battery consumption, I don't
want to get into the Wireless issues, except as they might impact FM.
------------------------------------------------------------------------
Predecessor single function products upon which the later integrated products are based:
2004: BRF6100 / BRF6150 = BT only
http://focus.ti.com/pdfs/wtbu/TI_brf6100_6150.pdf
2005: WiLink 4.0 mWLAN (WL1251 and WL1253) = WF only
WL1251 = 802.11 b/g/e/i/d/k
WL1253 = 802.11 a/b/g/e/i/d/k/h/j
http://focus.ti.com/pdfs/wtbu/wl1251_1253_prod_bulletin.pdf
2005: BlueLink 5.0 BRF6300 = BT only
http://focus.ti.com/pdfs/wtbu/ti_bluelink_5_brf6300.pdf
------------------------------------------------------------------------
Combined products. All seem to support FM Rx and Tx:
2007: BlueLink 6.0 BRF6350 = BT + FM
http://focus.ti.com/pdfs/wtbu/ti_bluelink_6_brf6350.pdf
200?: WiLink 5.0 = WiLink 4.0 mWLAN + BlueLink 6.0 = WF + BT + FM
http://focus.ti.com/general/docs/wt...ateId=6123&navigationId=12661&contentId=15402
2010: WiLink 6.0 = WF + BT + FM (Bluetooth (2.1?) Low Energy Specification 4.0 + EDR)
WL1271 = 802.11 b/g/n (2.4 GHz)
WL1273 = 802.11 a/b/g/n (2.4 & 5 GHz)
http://www.ti.com/lit/swmt013
2010.1: BlueLink / WiLink 7.0 BL6450 = BT 2.1 (+EDR) + FM (No WF)
http://focus.ti.com/pdfs/wtbu/BlueLink7_BL6450_swmt014d.pdf
2010.2: WiLink 7.0 = WF + BT + FM + GPS
WL1281 / WL1283 = 802.11 a/b/g/n + BT 3.0 + FM + GPS 3GPP
http://focus.ti.com/pdfs/wtbu/WiLink7_WL1283_swmt016.pdf

Sources
Sources
The source of information I've found include:
- Documents from TI or customers. Usually these contain limited information.
- Source code from TI, TI's customers or other parties, including ROM builders.
- Threads/Posts on forums including this one, as well as TI support forums.
- Miscellaneous random sources such as IRC logs for HTC-Linux.
The most comprehensive and easily useful sources I've found so far are the source codes
for a Linux WL1271 driver being produced by a Nokia employee, and somewhat similar
source codes from TI.
The "Texas Instruments WL1273 FM radio" Linux driver is under development by Matti J. Aaltonen
of Nokia. I believe the Nokia N900 uses a TI chip under Maemo->Meego, and perhaps other Nokia
devices too. Various patches and discussions are underway, and can be googled, and parts of it
are slowly appearing in the latest kernel source. If you want to see the latest, the only easy way
seems to be downloading one of the latest kernels at https://lkml.org/ .
There's an ancient first version from and some discussion from April here:
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/18449
I used http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.37.tar.bz2 and
http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.37.bz2 but I see there's a 2.6.38 RC5
there as well.
Finding and downloading TI code has been a pain, but they have a lot there.
TI WL 128x FM V4L2 driver:
There's a git repository for what appears to be an alternate V4L driver at http://dev.omapzoom.org/pub/scm/manju/L24x-btfm.git
Some discussion: http://www.spinics.net/lists/linux-media/msg28310.html
I'm not sure why there appear to be two efforts underway to create FM V4L2 drivers, the one by Nokia and the other by TI.
This appears to be source for TI's fmapp test utility and fm_stack library in a form that can be viewed by browser:
http://git.omapzoom.org/?p=platform...2a9dcca2dced00e724a2eb1dec578152f5beb;hb=HEAD
I managed to download the older 0.12 version of fmapp and fm_stack source code from somewhere, but can't recall where.
The "fmapp" utility has a LOT of functionality for testing just about every exposed FM feature, including RDS.
There is also a recently released "Android Froyo DevKit V2" at:
http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/02_00_00/index_FDS.html
You have to sign in for that but it should be easy to create an account. I already had one via a previous TI adventure.
The K2 BM6350 module PDFs have some further info:
http://www.ktwo.co.in/index.php?option=com_content&task=view&id=178&Itemid=465
http://www.ktwo.co.in/pdf/K2BM6350_Datasheet.pdf
http://www.ktwo.co.in/pdf/K2-BM6350 StarterKit UserManual.pdf
Forum threads:
[TUTORIAL] Reverse engineering HTC FM Radio for noobs (on EVO 4G)
http://forum.xda-developers.com/showthread.php?t=725870
Decompiled HTC Radio app
http://martinmarinov.info/HTCRadio.rar
Some words about bluetooth....
http://forum.xda-developers.com/showthread.php?t=816019
[Q] FM Radio app, Broadcom BCM4329 chipset
http://forum.xda-developers.com/showthread.php?t=837691
[THINK TANK] Enabling the Nexus One FM radio ...
http://forum.xda-developers.com/showthread.php?t=707404
FM Radio on 2.x ROMs - An Idea
http://forum.xda-developers.com/showthread.php?p=11366697

Devices
Devices
List of devices and FM chips. At this time I'd like to limit this to Android devices, but might consider others.
Would be useful to list limitations here. For example, some Motorola Droid owners were understandably disheartened,
after much work, to find they had no Fm Rx antenna connection, and could not make one without opening up the cans, etc.
on the board. So technically they had Fm Rx, practically, they had none.
Also, some boards may have no Tx antenna, but might possibly work within a few inches of an external FM receiver antenna.
--------------------------------------------------------------------------------
TI FM devices:
--------------------------------------------------------------------------------
HTC Legend: WL1273
HTC Tattoo/Click WL1271?
HTC Dream/Google G1 WL1271?
HTC Sapphire/Hero BRF6300 = WL1271?
HTC Diamond/Raphael/Blackstone BRF6350 (Windows Mobile?)
Motorola Droid WL1271
Motorola Backflip WL1271?
Motorola Milestone WL1273?
Nokia N900 WL1273? (Maemo?)
Barnes & Noble Nook Color WL1273?
--------------------------------------------------------------------------------
Broadcom FM devices:
--------------------------------------------------------------------------------
HTC Nexus One: 43xx
--------------------------------------------------------------------------------

FM Apps and APIs
FM Apps and APIs
Many handset manufacturers provide their own proprietary FM radio apps. Some people have managed to get an
FM radio app meant for another device working on theirs. Most, however, have library or other issues with a foreign app.
AFAICT, Google has not released any sanctioned FM radio API, nor do they intend to. I'd guess FM radio likely
won't bring much revenue to Google or the carriers.
In an ideal world, Android apps would use the same API as on Linux: the "Video For Linux version Two" aka V4L2.
This API makes use of a /dev/radioX device. This is somewhat similar to the /dev/videoX devices that some devices
appear to support for cameras.
If the V4L2 API was available on Android, Android FM radio apps could then be ported more easily from Linux.
Alas, there are relatively few Linux radio apps. GnomeRadio hasn't been touched in over 2 years and Gnome
doesn't run on Android anyway of course. Some command line apps could be ported, but that doesn't make for
an Android app.
So thus far, the defacto "API" for FM radio on Android has been vendor specific commands over HCI, the
Bluetooth interface. This is more or less similar to the way it can be done via I2C, but apparently
most FM chips are not wired via 12C; they use the existing HCI UART. Once again, FM radio is the
poor neglected "step-child".
One advantage of using HCI is that no new kernel drivers are needed. A disadvantage is that some mediation
driver would be required to use bluetooth and FM at the same time; the only alternative being drivers for
both smashed together, but that would be an Android specific hack and is not a good idea.
I've noted that one individual created an API spec and an app for Windows devices a few years back.
I believe it was called GFMRadio and XFMRadio or similar. That project was apparently abandoned.
MIUI released a GPL licensed FM app for some phones based on broadcom chips; HTC Desire and Nexus One.
The source code contains the string "/dev/radio", but AFAICT it doesn't appear to actually use V4L API.
It speaks directly to the broadcom FM chip via HCI.
Since MIUI source is GPL and available it could be used as a base for a TI, or TI and broadcom specific app.
In theory patches could be submitted to MIUI but I'm not sure they are open to that and the language barrier
from English to Chinese and back may be difficult.
Some interesting posts on MIUI here: http://forum.xda-developers.com/showthread.php?t=837691
http://www.miui.com/thread-1687-1-1.html
Using hcitool commands, or similar, one could write a radio app in bash or Perl etc. LOL.
TI has an "fmapp" command line testing utility that relies on libfm_stack.so .
This app won't run on my Legend because it depends on snd_ctl_* APIs in libaudio.
"strings libfm_stack.so" produces lots of interesting detail and embedded BTS scripts.
The source code I've found for TI fmapp, and it's FM stack library does not seem to have all
the functionality I've seen in the binary fmapp I found. So they may have stripped much code
for the publicly released source code.

Audio routing
Audio routing
On HTC phones, FM analog audio routing can be achieved by:
# Default
adb shell 'echo "disable" > /sys/class/htc_accessory/fm/flag'
# Headset
adb shell 'echo "fm_headset" > /sys/class/htc_accessory/fm/flag'
# Speaker
adb shell 'echo "fm_speaker" > /sys/class/htc_accessory/fm/flag'
# View
adb shell cat /sys/class/htc_accessory/fm/flag

Firmware, TI BTS file, HCI and I2S/I2C issues, tools etc.
Firmware, TI BTS file, HCI and I2S/I2C issues, tools etc.
The Nokia V4L driver loads radio-wl1273-fw.bin, although the code does indicate it may not be necessary.
I can't find this firmware file anywhere. As with many other firmwares, it may simply be a known firmware
file renamed. This has been noted with other firmware files for the TI radio.
Information on firmware for these TI chips seems scattered and incomplete. Same with the BTS Bluetooth script files
which are usually important for accessing the FM functionality.
I think one of the reasons for this lack of information is that most parties do not want us messing with the available functionality.
- Device manufacturers do not want their devices used in violation of FCC or other regulatory body rules.
For example, FM transmission at higher power levels or improper frequencies. Also RDS transmissions with bogus data.
- Device manufacturers and carriers want us to buy newer or more expensive products for additional functionality.
They also would rather we use voice minutes instead of FM "walkie talkies".
- Google and carriers want us to stream music via data rather than pick it up for free from over the air.
...
Where do I find utilities to dump/decode/encode BTS files ?
....
HCI is usually used to access FM functions, but I2C might be usable on some devices.
...
fm_rx_init_6350.1.bts
fm_rx_init_6350.2.bts
fm_rx_init_6450.1.bts
fm_tx_init_6450.1.bts
fmc_init_6350.1.bts
fmc_init_6350.2.bts
fmc_init_6450.1.bts
tiinit_0.0.0.bts
tiinit_5.2.34.bts
tiinit_5.3.53.bts
tiinit_6.1.24.bts
tiinit_6.2.31.bts

HCI/I2C Commands
HCI/I2C Commands
Most of this information is gleaned from:
- The Linux WL1271 FM Radio source code written by a Nokia employee.
- TI source code for fmapp/fmstack, etc.
Various forum posts also make it clear there is a bewildering array of commands etc. not referenced in the source codes above.
Some information can also be retrieved by looking inside BTS, firmware, app, utility and library etc. files.
...
Vendor Specific Opcodes for the various FM-related commands over HCI. (_FmcCoreTransportFmCOmmands)
_FMC_CMD_I2C_FM_READ 0x0133
_FMC_CMD_FM_I2C_FM_READ_HW_REG 0x0134
_FMC_CMD_I2C_FM_WRITE 0x0135
?0x136
_FMC_CMD_FM_POWER_MODE 0x0137
?0x138
_FMC_CMD_FM_SET_AUDIO_PATH 0x0139
_FMC_CMD_FM_CHANGE_I2C_ADDR 0x013A
Format of an HCI READ/WRITE command to FM over I2C is:
HCI Header:
- HCI Packet Type: (Added internally by the HCI Transport Layer)
- HCI Opcode: 2 bytes (LSB, MSB - LE)
- HCI Parameters Total Len: 1 byte (total length of all subsequent fields)
HCI Parameters:
- FM Opcode: 1 byte
- FM Parameters Len: 2 bytes (LSB, MSB - LE)
- FM Cmd Parameter Value: N bytes
For "simple" (non-RDS) read commands "FM Parameters Len" is always "2, 0" (2).
...

HCI/I2C Commands/Opcodes, registers, values
HCI/I2C Opcodes, registers, values.
Most of this information is gleaned from:
- The Linux WL1271 FM Radio source code written by a Nokia employee.
- TI source code for fmapp/fmstack, etc.
---------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
The most important "commands":
----------
0x137 FM_POWER_MODE: FM Core power up (last byte 0=down, 1=up)
Usage:
# FM_POWER_MODE: FM Core power up
adb shell hcitool cmd 0x3f 0x137 0x01 0x01
# FM_POWER_MODE: FM Core power down
adb shell hcitool cmd 0x3f 0x137 0x01 0x00
----------
0x133 FM_READ
Examples:
# FM_READ: POWER (Register 0x20)
adb shell hcitool cmd 0x3f 0x133 0x20 0x02 0x00
# FM_READ: RSSI (Register 0x01)
adb shell hcitool cmd 0x3f 0x133 0x01 0x02 0x00
----------
0x135 FM_WRITE
Examples:
# FM WRITE: POWER: Rx on (This actually seems to be "audio enable" !
adb shell hcitool cmd 0x3f 0x135 0x20 0x02 0x00 0x00 0x02
# FM WRITE: POWER: Rx on plus RDS
adb shell hcitool cmd 0x3f 0x135 0x20 0x02 0x00 0x00 0x03
----------
------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
The "registers": (some call them opcodes, but they seem to be registers IMO)
0x00 0 WL1273_STEREO_GET FMC_FW_OPCODE_RX_STEREO_GET
0 FM_STEREO_MODE mono (or no signal ?)
1 FM_MONO_MODE stereo signal
0x01 1 WL1273_RSSI_LVL_GET FMC_FW_OPCODE_RX_RSSI_LEVEL_GET
(-128) SCHAR_MIN FM_RX_RSSI_THRESHOLD_MIN See also WL1273_SEARCH_LVL_SET
127 SCHAR_MAX FM_RX_RSSI_THRESHOLD_MAX
0x02 2 WL1273_IF_COUNT_GET FMC_FW_OPCODE_RX_IF_COUNT_GET
# changes: 1, 2, 3, ff, fe, 0
0x03 3 WL1273_FLAG_GET FMC_FW_OPCODE_CMN_FLAG_GET
? = Event masks ?
#define FM_FR_EVENT (1 << 0)
#define FM_BL_EVENT (1 << 1)
#define FM_RDS_EVENT (1 << 2)
#define FM_BBLK_EVENT (1 << 3)
#define FM_LSYNC_EVENT (1 << 4)
#define FM_LEV_EVENT (1 << 5)
#define FM_IFFR_EVENT (1 << 6)
#define FM_PI_EVENT (1 << 7)
#define FM_PD_EVENT (1 << 8)
#define FM_STIC_EVENT (1 << 9)
#define FM_MAL_EVENT (1 << 10)
#define FM_POW_ENB_EVENT (1 << 11)
0x04 4 WL1273_RDS_SYNC_GET FMC_FW_OPCODE_RX_RDS_SYNC_GET
0 WL1273_RDS_NOT_SYNCHRONIZED
1 WL1273_RDS_SYNCHRONIZED
0x05 5 WL1273_RDS_DATA_GET FMC_FW_OPCODE_RX_RDS_DATA_GET
64 FMC_FW_RX_RDS_THRESHOLD (*1 or *3) See also FMC_FW_OPCODE_RX_RDS_MEM_SET_GET
85 FMC_FW_RX_RDS_THRESHOLD_MAX Used as FMC_FW_RX_RDS_THRESHOLD_MAX*RDS_BLOCK_SIZE for mem size.
? Set to 3e 16 ? (15894)
0x06 ? Set to 1 ?
------------------------------------------------------------------------------------------
Codes 6-9 missing
------------------------------------------------------------------------------------------
0x0a 10 WL1273_FREQ_SET FMC_FW_OPCODE_RX_FREQ_SET_GET
base + freq / 50Khz
0 0x000 87500 WL1273_BAND_OTHER_LOW
410 0x19a 108000 WL1273_BAND_OTHER_HIGH
0 0x000 76000 WL1273_BAND_JAPAN_LOW
280 0x118 90000 WL1273_BAND_JAPAN_HIGH
? #define FM_UNDEFINED_FREQ 0xFFFFFFFF
0x0b 11 WL1273_AF_FREQ_SET FMC_FW_OPCODE_RX_AF_FREQ_SET_GET
0x0c 12 WL1273_MOST_MODE_SET FMC_FW_OPCODE_RX_MOST_MODE_SET_GET ! MOST = "MOno/STereo"
0 WL1273_RX_STEREO Stereo according to blend
1 WL1273_RX_MONO Force mono output
0 FM_STEREO_MODE
1 FM_MONO_MODE
0x0d 13 WL1273_MOST_BLEND_SET FMC_FW_OPCODE_RX_MOST_BLEND_SET_GET
0 Switched blend & hysteresis
1 FM_STEREO_SOFT_BLEND Soft blend
Now set to 1 = Soft blend
0x0e 14 WL1273_DEMPH_MODE_SET FMC_FW_OPCODE_RX_DEMPH_MODE_SET_GET
0 FM_RX_EMPHASIS_FILTER_50_USEC
1 FM_RX_EMPHASIS_FILTER_75_USEC
0x0f 15 WL1273_SEARCH_LVL_SET FMC_FW_OPCODE_RX_SEARCH_LVL_SET_GET
7 WL1273_DEFAULT_SEEK_LEVEL
(-128) SCHAR_MIN See also WL1273_RSSI_LVL_GET
127 SCHAR_MAX
0x10 16 WL1273_BAND_SET FMC_FW_OPCODE_RX_BAND_SET_GET
0 WL1273_BAND_OTHER 87.5-108 Mhz North America, Europe, generally rest of world besides Japan
1 WL1273_BAND_JAPAN 76-90 Mhz Japan (perhaps soon US also)
0x11 17 WL1273_MUTE_STATUS_SET FMC_FW_OPCODE_RX_MUTE_STATUS_SET_GET
0 ........ FMC_FW_RX_MUTE_UNMUTE_MODE
bit0 0x01 WL1273_MUTE_SOFT_ENABLE FMC_FW_RX_MUTE_RF_DEP_MODE
bit1 0x02 WL1273_MUTE_AC FMC_FW_RX_MUTE_AC_MUTE_MODE
bit2 0x04 WL1273_MUTE_HARD_LEFT FMC_FW_RX_MUTE_HARD_MUTE_LEFT_MODE
bit3 0x08 WL1273_MUTE_HARD_RIGHT FMC_FW_RX_MUTE_HARD_MUTE_RIGHT_MODE
bit4 0x10 WL1273_MUTE_SOFT_FORCE FMC_FW_RX_MUTE_SOFT_MUTE_FORCE_MODE
Set to one of these:
2 0x02 FM_RX_AC_MUTE_MODE Mute On But enable soft/attenuate ?
0 0x00 FM_RX_UNMUTE_MODE Mute Off
16 0x10 FM_RX_SOFT_MUTE_FORCE_MODE Mute Attenuate
Then optionally logically "OR" ('|') this:
bit0 0x01 FM_RX_RF_DEP_MODE
Optional bits ?
bit2 0x04 FM_RX_HARD_MUTE_LEFT_MODE
bit3 0x08 FM_RX_HARD_MUTE_RIGHT_MODE
? #define FM_MUTE_OFF 0
? #define FM_MUTE_ON 1
? #define FM_MUTE_ATTENUATE 2
? #define FM_RX_RF_DEPENDENT_MUTE_ON 1
? #define FM_RX_RF_DEPENDENT_MUTE_OFF 0
0x12 18 WL1273_RDS_PAUSE_LVL_SET FMC_FW_OPCODE_RX_RDS_PAUSE_LVL_SET_GET
? Set to 5 ?
0x13 19 WL1273_RDS_PAUSE_DUR_SET FMC_FW_OPCODE_RX_RDS_PAUSE_DUR_SET_GET
? Set to 0x0c = 12
0x14 20 WL1273_RDS_MEM_SET FMC_FW_OPCODE_RX_RDS_MEM_SET_GET
64 FMC_FW_RX_RDS_THRESHOLD (*1 or *3) See also FMC_FW_OPCODE_RX_RDS_DATA_GET
85 FMC_FW_RX_RDS_THRESHOLD_MAX Used as FMC_FW_RX_RDS_THRESHOLD_MAX*RDS_BLOCK_SIZE for mem size.
Set to 0x55 = 85 = Max Thresh
0x15 21 WL1273_RDS_BLK_B_SET FMC_FW_OPCODE_RX_RDS_BLK_B_SET_GET
0x16 22 WL1273_RDS_MSK_B_SET FMC_FW_OPCODE_RX_RDS_MSK_B_SET_GET
0x17 23 WL1273_RDS_PI_MASK_SET FMC_FW_OPCODE_RX_RDS_PI_MASK_SET_GET
0x18 24 WL1273_RDS_PI_SET FMC_FW_OPCODE_RX_RDS_PI_SET_GET
0x19 25 WL1273_RDS_SYSTEM_SET FMC_FW_OPCODE_RX_RDS_SYSTEM_SET_GET
0 FM_RDS_SYSTEM_RDS
1 FM_RDS_SYSTEM_RBDS
0x1a 26 WL1273_INT_MASK_SET FMC_FW_OPCODE_CMN_INT_MASK_SET_GET
0x1b 27 WL1273_SEARCH_DIR_SET FMC_FW_OPCODE_RX_SEARCH_DIR_SET_GET
0 FM_SEARCH_DIRECTION_DOWN
1 FM_SEARCH_DIRECTION_UP
0x1c 28 WL1273_VOLUME_SET FMC_FW_OPCODE_RX_VOLUME_SET_GET
880 0x370 ........ FMC_FW_RX_FM_GAIN_STEP ? 35 steps ?
0 0x00 ........ FMC_FW_RX_FM_VOLUMN_MIN
30904 0x78b8 WL1273_DEFAULT_VOLUME FMC_FW_RX_FM_VOLUMN_INITIAL_VALUE
61808 0xf170 ........ FMC_FW_RX_FM_VOLUMN_MAX
65535 0xffff WL1273_MAX_VOLUME ........
- #define FM_RX_VOLUME_MIN 0
? #define FM_RX_VOLUME_MAX 70
? #define FM_RX_VOLUME_GAIN_STEP 0x370
0x1d 29 WL1273_AUDIO_ENABLE FMC_FW_OPCODE_RX_AUDIO_ENABLE_SET_GET
bit0 0x01 WL1273_AUDIO_ENABLE_I2S FMC_FW_RX_FM_AUDIO_ENABLE_I2S
bit1 0x02 WL1273_AUDIO_ENABLE_ANALOG FMC_FW_RX_FM_AUDIO_ENABLE_ANALOG
bit0|1 0x03 ........ FMC_FW_RX_FM_AUDIO_ENABLE_I2S_AND_ANALOG
0 ........ FMC_FW_RX_FM_AUDIO_ENABLE_DISABLE
0x1e 30 WL1273_PCM_MODE_SET FMC_FW_OPCODE_CMN_I2S_CLOCK_CONFIG_SET_GET
0 0x00 WL1273_PCM_DEF_MODE ? I2S protocol, left channel first, data width 16 bits
0x1f 31 WL1273_I2S_MODE_CONFIG_SET FMC_FW_OPCODE_CMN_I2S_MODE_CONFIG_SET_GET
0x0145= WL1273_IS2_RATE_48K(0) | IS2_TRI_OPT(0) | IS2_SDOWS_RF(0x0100) |
IS2_SLAVEW(0x0040) | IS2_FORMAT_STD(0) | IS2_WIDTH_50(0x0005)
0 0x0 WL1273_IS2_WIDTH_32
1 0x1 WL1273_IS2_WIDTH_40
2 0x2 WL1273_IS2_WIDTH_22_23
3 0x3 WL1273_IS2_WIDTH_23_22
4 0x4 WL1273_IS2_WIDTH_48
5 0x5 WL1273_IS2_WIDTH_50
6 0x6 WL1273_IS2_WIDTH_60
7 0x7 WL1273_IS2_WIDTH_64
8 0x8 WL1273_IS2_WIDTH_80
9 0x9 WL1273_IS2_WIDTH_96
10 0xa WL1273_IS2_WIDTH_128
bits0-3 0xf WL1273_IS2_WIDTH 0xf Mask
........
0 0x00 WL1273_IS2_FORMAT_STD (0x0 << 4)
16 0x10 WL1273_IS2_FORMAT_LEFT (0x1 << 4)
32 0x20 WL1273_IS2_FORMAT_RIGHT (0x2 << 4)
48 0x30 WL1273_IS2_FORMAT_USER (0x3 << 4)
........
0 0x00 WL1273_IS2_MASTER (0x0 << 6)
64 0x40 WL1273_IS2_SLAVEW (0x1 << 6)
........
0 0x00 WL1273_IS2_TRI_AFTER_SENDING (0x0 << 7)
128 0x80 WL1273_IS2_TRI_ALWAYS_ACTIVE (0x1 << 7)
........
0 0x00 WL1273_IS2_SDOWS_RR (0x0 << 8)
256 0x100 WL1273_IS2_SDOWS_RF (0x1 << 8)
512 0x200 WL1273_IS2_SDOWS_FR (0x2 << 8)
768 0x300 WL1273_IS2_SDOWS_FF (0x3 << 8)
........
0 0x00 WL1273_IS2_TRI_OPT (0x0 << 10)
1024 0x400 WL1273_IS2_TRI_ALWAYS (0x1 << 10)
........
0 0x00 WL1273_IS2_RATE_48K (0x0 << 12)
4096 0x1000 WL1273_IS2_RATE_44_1K (0x1 << 12)
8192 0x2000 WL1273_IS2_RATE_32K (0x2 << 12)
16384 0x4000 WL1273_IS2_RATE_22_05K (0x4 << 12) ?! No 0x3, 0x6-0x7, 0xb-0xe ?
20480 0x5000 WL1273_IS2_RATE_16K (0x5 << 12)
32768 0x8000 WL1273_IS2_RATE_12K (0x8 << 12)
36864 0x9000 WL1273_IS2_RATE_11_025 (0x9 << 12)
40960 0xa000 WL1273_IS2_RATE_8K (0xa << 12)
61440 0xf000 WL1273_IS2_RATE (0xf << 12) Mask
........
0 WL1273_I2S_DEF_MODE WL1273_IS2_WIDTH_32| WL1273_IS2_FORMAT_STD| WL1273_IS2_MASTER| WL1273_IS2_TRI_AFTER_SENDING|
WL1273_IS2_SDOWS_RR| WL1273_IS2_TRI_OPT| WL1273_IS2_RATE_48K
0x20 32 WL1273_POWER_SET FMC_FW_OPCODE_RX_POWER_SET_GET
0 WL1273_POWER_SET_OFF FMC_FW_RX_POWER_SET_FM_AND_RDS_OFF
! 0 just seems to mute output. RSSI still responds and all registers remain set.
bit0 0x01 WL1273_POWER_SET_FM FMC_FW_RX_POWER_SET_FM_ON_RDS_OFF
bit1 0x02 WL1273_POWER_SET_RDS ........
bit0|1 0x03 ........ FMC_FW_RX_POWER_SET_FM_AND_RDS_ON
bit4 0x10 WL1273_POWER_SET_RETENTION ........
0x21 33 WL1273_INTX_CONFIG_SET FMC_FW_OPCODE_CMN_INTX_CONFIG_SET_GET
0x22 34 WL1273_PULL_EN_SET FMC_FW_OPCODE_CMN_PULL_EN_SET_GET
? Set to 0xff = 255 ?
0x23 35 WL1273_HILO_SET FMC_FW_OPCODE_RX_HILO_SET_GET
0 0x0 FM_RX_IFFREQ_TO_HI_SIDE
1 0x1 FM_RX_IFFREQ_TO_LO_SIDE
2 0x2 FM_RX_IFFREQ_HILO_AUTOMATIC
Set to 1 = FM_RX_IFFREQ_TO_LO_SIDE
0x24 36 WL1273_SWITCH2FREF FMC_FW_OPCODE_CMN_SWITCH_2_FREF_SET
0x25 37 WL1273_FREQ_DRIFT_REPORT FMC_FW_OPCODE_CMN_FREQ_DRIFT_REPORT_SET TI fmc_fw_defs.h error defines as 0x24
0x28 40 WL1273_PCE_GET FMC_FW_OPCODE_CMN_PCE_GET
Set to 0x0f = 15
0x29 41 WL1273_FIRM_VER_GET FMC_FW_OPCODE_CMN_FIRM_VER_GET
Set to 2
0x2a 42 WL1273_ASIC_VER_GET FMC_FW_OPCODE_CMN_ASIC_VER_GET
Set to 2
0x2b 43 WL1273_ASIC_ID_GET FMC_FW_OPCODE_CMN_ASIC_ID_GET
Set to 0x1273 = 4723
0x2c 44 WL1273_MAN_ID_GET FMC_FW_OPCODE_CMN_MAN_ID_GET
Set to 0x17 = 23
0x2d 45 WL1273_TUNER_MODE_SET FMC_FW_OPCODE_RX_TUNER_MODE_SET
0 TUNER_MODE_STOP_SEARCH FMC_FW_RX_TUNER_MODE_STOP_SEARCH
1 TUNER_MODE_PRESET FMC_FW_RX_TUNER_MODE_PRESET_MODE
2 TUNER_MODE_AUTO_SEEK FMC_FW_RX_TUNER_MODE_AUTO_SEARCH_MODE (AUTONOMOUS)
3 TUNER_MODE_AF FMC_FW_RX_TUNER_MODE_ALTER_FREQ_JUMP
4 TUNER_MODE_AUTO_SEEK_PI ........
5 TUNER_MODE_AUTO_SEEK_BULK ........
0x2e 46 WL1273_STOP_SEARCH FMC_FW_OPCODE_RX_STOP_SEARCH
0x2f 47 WL1273_RDS_CNTRL_SET FMC_FW_OPCODE_RX_RDS_CNTRL_SET
1 FMC_FW_RX_RDS_FLUSH_FIFO
------------------------------------------------------------------------------------------
Codes 48-51 (0x30-0x33) missing
------------------------------------------------------------------------------------------
0x32 ? Set to 0xC000 = 49152
------------------------------------------------------------------------------------------
0x34 52 WL1273_SOC_INT_TRIGGER
------------------------------------------------------------------------------------------
Code 53 (0x35) missing
Code 54 (0x36) and up are mostly TX, except:
0x57 87 WL1273_RX_ANTENNA_SELECT ........
and the common/CMN values 100-102, 254, 255
------------------------------------------------------------------------------------------
0x36 54 WL1273_TX_AUDIO_INPUT_LEVEL_RANGE_SET
0x37 55 WL1273_CHANL_SET FMC_FW_OPCODE_TX_CHANL_SET_GET
freq / 10Khz
7600 0x1db0 76000 WL1273_BAND_TX_LOW
10800 0x2a30 108000 WL1273_BAND_TX_HIGH
0x38 56 WL1273_SCAN_SPACING_SET FMC_FW_OPCODE_TX_CHANL_BW_SET_GET
1 WL1273_SPACING_50kHz FMC_FW_TX_CHANNEL_BW_50_KHZ
2 WL1273_SPACING_100kHz FMC_FW_TX_CHANNEL_BW_100_KHZ
4 WL1273_SPACING_200kHz FMC_FW_TX_CHANNEL_BW_200_KHZ
Set to 4 = 200 KHz
1 0x1 FM_CHANNEL_SPACING_50KHZ
2 0x2 FM_CHANNEL_SPACING_100KHZ
4 0x4 FM_CHANNEL_SPACING_200KHZ
0x39 57 WL1273_REF_SET ........
0x3a 58 WL1273_POWER_ATT_SET ........
0x3b 59 WL1273_POWER_LEV_SET FMC_FW_OPCODE_TX_POWER_LEVEL_SET_GET
Set to 4
/* Range for TX power level in units for dB/uV */ ! 122-pwr
#define FM_PWR_LVL_LOW 91
#define FM_PWR_LVL_HIGH 122
/* Chip specific default TX power level value */
#define FM_PWR_LVL_DEF 4
0x3c 60 WL1273_AUDIO_DEV_SET ........
0x109 = 265 ?
0x3d 61 WL1273_PILOT_DEV_SET ........
0x1b = 27
0x3e 62 WL1273_RDS_DEV_SET ........
8
0x3f 63 WL1273_AUDIO_IO_SET FMC_FW_OPCODE_TX_AUDIO_IO_SET
0 WL1273_AUDIO_IO_SET_ANALOG FMC_FW_TX_AUDIO_IO_SET_ANALOG
1 WL1273_AUDIO_IO_SET_I2S FMC_FW_TX_AUDIO_IO_SET_I2S
0x40 64 WL1273_PREMPH_SET FMC_FW_OPCODE_TX_PREMPH_SET_GET
0 FM_TX_PREEMPH_50US FM TX Pre-emphasis filter default ?
1 FM_TX_PREEMPH_OFF
2 FM_TX_PREEMPH_75US
0x41 65 TX_BAND_SET !!??
0x42 66 WL1273_MONO_SET FMC_FW_OPCODE_TX_MONO_SET_GET
0 WL1273_TX_MONO
1 WL1273_TX_STEREO
1 by default
0x43 67 WL1273_MPX_LMT_ENABLE
0x44 68 ........ FMC_FW_OPCODE_TX_PI_CODE_SET_GET
0x45 69 WL1273_ECC_SET FMC_FW_OPCODE_TX_RDS_ECC_SET_GET
0x46 70 WL1273_PTY FMC_FW_OPCODE_TX_RDS_PTY_CODE_SET_GET
0x47 71 WL1273_AF FMC_FW_OPCODE_TX_RDS_AF_SET_GET
------------------------------------------------------------------------------------------
Code 72 (0x48) missing
------------------------------------------------------------------------------------------
0x49 73 WL1273_TX_AUDIO_LEVEL_TEST_THRESHOLD ........
0x4a 74 WL1273_DISPLAY_MODE FMC_FW_OPCODE_TX_RDS_PS_DISPLAY_MODE_SET_GET
0 FMC_FW_TX_RDS_PS_DISPLAY_MODE_SCROLL_OFF
1 FMC_FW_TX_RDS_PS_DISPLAY_MODE_SCROLL_ON
0x4d 77 WL1273_RDS_REP_SET FMC_FW_OPCODE_TX_RDS_REPERTOIRE_SET_GET
0x4e 78 WL1273_TA_SET FMC_FW_OPCODE_TX_RDS_TA_SET
0x4f 79 WL1273_TP_SET FMC_FW_OPCODE_TX_RDS_TP_SET
0x50 80 WL1273_DI_SET FMC_FW_OPCODE_TX_RDS_DI_CODES_SET_GET
0x51 81 WL1273_MS_SET FMC_FW_OPCODE_TX_RDS_MUSIC_SPEECH_FLAG_SET_GET
0x52 82 WL1273_PS_SCROLL_SPEED FMC_FW_OPCODE_TX_RDS_PS_SCROLL_SPEED_SET_GET
0x53 83 WL1273_SOC_AUDIO_PATH_SET ........
0x54 84 WL1273_SOC_PCMI_OVERRIDE ........
0x55 85 WL1273_SOC_I2S_OVERRIDE ........
0x56 86 WL1273_I2C_DEV_ADDR_SET ........
default 0x22 = 34 (Nokia: #define RX71_FM_I2C_ADDR 0x22)
0x57 87 WL1273_RX_ANTENNA_SELECT ........
0x58 88 WL1273_REF_ERR_CALIB_PARAM_SET ........
0x0c = 12
0x59 89 WL1273_REF_ERR_CALIB_PERIODICITY_SET ........
0x5a 90 WL1273_POWER_ENB_SET FMC_FW_OPCODE_TX_POWER_ENB_SET
0 FMC_FW_TX_POWER_DISABLE
1 FMC_FW_TX_POWER_ENABLE
0x5b 91 WL1273_PUPD_SET FMC_FW_OPCODE_TX_POWER_UP_DOWN_SET
0 WL1273_PUPD_SET_OFF FMC_FW_TX_POWER_DOWN
bit0 1 WL1273_PUPD_SET_ON FMC_FW_TX_POWER_UP
bit4 0x10 WL1273_PUPD_SET_RETENTION ........
0x5c 92 WL1273_MUTE FMC_FW_OPCODE_TX_MUTE_MODE_SET_GET
0 FMC_FW_TX_UNMUTE
1 FMC_FW_TX_MUTE
0x5d 93 WL1273_PI_SET ........
0x5e 94 WL1273_RDS_DATA_ENB FMC_FW_OPCODE_TX_RDS_DATA_ENB_SET_GET
0 FMC_FW_TX_RDS_ENABLE_STOP
1 FMC_FW_TX_RDS_ENABLE_START
0x5f 95 WL1273_RSSI_BLOCK_SCAN_FREQ_SET ........
0x60 96 WL1273_TX_AUDIO_LEVEL_TEST ........
0x61 97 WL1273_RSSI_BLOCK_SCAN_START ........
0x62 98 WL1273_RDS_CONFIG_DATA_SET FMC_FW_OPCODE_TX_RDS_CONFIG_DATA_SET
0x63 99 WL1273_RDS_DATA_SET FMC_FW_OPCODE_TX_RDS_DATA_SET
0x64 100 WL1273_WRITE_HARDWARE_REG FMC_FW_OPCODE_CMN_HARDWARE_REG_SET_GET
0x65 101 WL1273_CODE_DOWNLOAD FMC_FW_OPCODE_CMN_CODE_DOWNLOAD
0x66 102 WL1273_RESET FMC_FW_OPCODE_CMN_RESET
0x0f00 = 3840
------------------------------------------------------------------------------------------
Code 103 (0x67) missing
------------------------------------------------------------------------------------------
0x68 104 WL1273_READ_FMANT_TUNE_VALUE ........ TX tuning capacitor value
?
/* FM TX antenna impedence values */
#define FM_TX_ANT_IMP_50 0
#define FM_TX_ANT_IMP_200 1
#define FM_TX_ANT_IMP_500 2
------------------------------------------------------------------------------------------
Codes 105-253 (0x69-0xfd) missing
------------------------------------------------------------------------------------------
0xfe 254 WL1273_FM_POWER_MODE ........
0 FMC_FW_RX_FM_POWER_MODE_DISABLE
1 FMC_FW_RX_FM_POWER_MODE_ENABLE
0xff 255 WL1273_FM_INTERRUPT ........
------------------------------------------------------------------------------------------
?
5 WL1273_RSSI_BLOCK_SCAN_DATA_GET RSSI_BLOCK_SCAN_DATA_GET
------------------------------------------------------------------------------------------
/*
Maximum length of data that may be sent in a single RDS data set command
Once FM FW team removes internal limitations, HCI limitations (much
longer) may apply.
In case a longer RDS data should be sent to the chip, it is divided into
multiple chunks, each chunk being up to FMC_FW_TX_MAX_RDS_DATA_SET_LEN
bytes long
*/
#define FMC_FW_TX_MAX_RDS_DATA_SET_LEN ((FMC_UINT)30)
/*
Defines the max length of data that can be written to FM Hardware register
*/
#define FMC_FW_WRITE_HARDWARE_REG_MAX_DATA_LEN ((FMC_UINT)HCI_CMD_PARM_LEN)
? HCI_CMD_PARM_LEN ?
------------------------------------------------------------------------------------------
Event masks:
bit, 2 hex bytes, (1), (2)
0 0x0001 WL1273_FR_EVENT FMC_FW_MASK_FR Tuning Operation Ended
1 0x0002 WL1273_BL_EVENT FMC_FW_MASK_BL Band limit was reached during search
2 0x0004 WL1273_RDS_EVENT FMC_FW_MASK_RDS RDS data threshold reached in FIFO buffer
3 0x0008 WL1273_BBLK_EVENT FMC_FW_MASK_BBLK RDS B block match condition occurred
4 0x0010 WL1273_LSYNC_EVENT FMC_FW_MASK_LSYNC RDS sync was lost
5 0x0020 WL1273_LEV_EVENT FMC_FW_MASK_LEV RSSI level has fallen below the threshold configured by SEARCH_LVL_SET
6 0x0040 WL1273_IFFR_EVENT FMC_FW_MASK_IFFR Received signal frequency is out of range
7 0x0080 WL1273_PI_EVENT FMC_FW_MASK_PI RDS PI match occurred
8 0x0100 WL1273_PD_EVENT FMC_FW_MASK_PD Audio pause detect occurred
9 0x0200 WL1273_STIC_EVENT FMC_FW_MASK_STIC Stereo indication changed
10 0x0400 WL1273_MAL_EVENT FMC_FW_MASK_MAL Hardware malfunction
11 0x0800 WL1273_POW_ENB_EVENT FMC_FW_MASK_POW_ENB Tx Power Enable/Disable
12 0x1000 WL1273_SCAN_OVER_EVENT FMC_FW_MASK_INVALID_PARAM
13 0x2000 WL1273_ERROR_EVENT !! One of the above is wrong !!
---------------------------------------------------------------------------------------------------------

FM Receiver script
---null set---

FM Transmitter script
---null set---

I think you are doing an awsome job and I really hope that you'll succeded. But the reason why I'm writing this post is to get this thread on the first page again for a while, so maybe more developers will see it, and can contribute !
Good luck!
EDIT: Perhaps it just needs more outstandig title, maybe Unviersal FM radio for android devices with TI WL chips, or something that would get people to read it.

qzem said:
I think you are doing an awsome job and I really hope that you'll succeded. But the reason why I'm writing this post is to get this thread on the first page again for a while, so maybe more developers will see it, and can contribute !
Good luck!
EDIT: Perhaps it just needs more outstandig title, maybe Unviersal FM radio for android devices with TI WL chips, or something that would get people to read it.
Click to expand...
Click to collapse
It's already off the first page, LOL.
My plan has been to post a link to this thread in the various existing threads for different devices using the TI FM chips. I'm sure that will get this thread some notice. I think a lot of devs and dev types stick to the forums for their devices and don't look at this general section.
At least there are so many potentially matching keywords in the first 10 posts that google searches on the subject are likely to link here.
I agonized over the thread title name for some time and "TI FM Radio" is best description I could think of, technically at least. I don't know if I can rename the thread, but it might help to put the names of popular devices with TI chips in the title.
As I posted on the Legend thread, I now have an App Inventor app up and running with functionality to tune, scan, change volume and see signal strength. The audio routing is the last major piece of the puzzle, but it may be different on different devices.
I'll spend a few more days at most to try and get audio routing working, and then, whether working or not, I'll post in a few threads looking for further info and people who want to try the app I'm building.
Would be nice to see the RDS and transmitter working soon too.

Regarding merging the bluetooth and FM drivers, TI's solution appears to be what they call a shared transport line discipline driver. The way this should work, each driver has what appears to it to be dedicated access to it's respective core, and the line discipline driver takes care of any queueing or delaying of commands & such that has to happen to keep them from stepping on each others toes.
Oh, and "IP" is "Intellectual Property" in this case. So the core, generally you'd say the WL127x has a wifi core, bluetooth core, etc. and 128x has a gps core as well. An IP core uses a description language (it used to be VHDL) to describe the layout of the core, so for instance if a company wants to build wifi onto their own chip, they can buy use of the IP core from TI instead of having to buy a phyiscal chip and interface to it.
I've got a debian install wedged onto my Droid 2 Global, I'm going to look into the "ti-st" V4L2 FM drivers, and see if I can get a module that will insert. The kernel can't be replaced on D2G yet, but as far as I know if I get a 2.6.32.9 kernel tree, and get ti-st driver to compile under it, I don't see why it shouldn't insert as a module just fine. Also, I'll look REAL closely to see if I can discern how it gets audio out, so I might have an hcitool command or two to add if that pans out.

hwertz said:
Regarding merging the bluetooth and FM drivers, TI's solution appears to be what they call a shared transport line discipline driver. The way this should work, each driver has what appears to it to be dedicated access to it's respective core, and the line discipline driver takes care of any queueing or delaying of commands & such that has to happen to keep them from stepping on each others toes.
Oh, and "IP" is "Intellectual Property" in this case. So the core, generally you'd say the WL127x has a wifi core, bluetooth core, etc. and 128x has a gps core as well. An IP core uses a description language (it used to be VHDL) to describe the layout of the core, so for instance if a company wants to build wifi onto their own chip, they can buy use of the IP core from TI instead of having to buy a phyiscal chip and interface to it.
I've got a debian install wedged onto my Droid 2 Global, I'm going to look into the "ti-st" V4L2 FM drivers, and see if I can get a module that will insert. The kernel can't be replaced on D2G yet, but as far as I know if I get a 2.6.32.9 kernel tree, and get ti-st driver to compile under it, I don't see why it shouldn't insert as a module just fine. Also, I'll look REAL closely to see if I can discern how it gets audio out, so I might have an hcitool command or two to add if that pans out.
Click to expand...
Click to collapse
Thanks for the info hwertz .
OK I understand "IP" now; never heard it used in that way to designate blocks on a chip.
Yes I read something about the line discipline. Some block diagrams: http://omappedia.org/wiki/Wilink_ST
If you know of any HCI commands dealing with audio routing, please post or pm whatever info you can share.
So I'd guess your opinion is that the v4l2 api is the best route to support FM radios on Android ? That was among my first thoughts until I saw that there is currently virtually no such support on any Android ROM I've heard of. HCI seems to work fine, but it requires chip specific commands of course.
Clearly though, at least Nokia and TI both are working on efforts to bring V4L2 apis for the TI chip in the embedded linux or Android environments.
I'm not sure how audio routing would be configured on Android when using v4l2 apis. The PC environment requires moving digital data from source to destination. But SOC devices often can move digital or analog data directly and without software support.

FM Transmitting Radius
So I hope this question is not too basic for this forum, but I'm new to it and wonder how large the FM transmitting radius of such a chip might be. I basically just need to get an idea, but of course I'd also be thankful if you can refer me to all sorts of literature, specs, overviews, etc.
Thanks!

Lipton1 said:
So I hope this question is not too basic for this forum, but I'm new to it and wonder how large the FM transmitting radius of such a chip might be. I basically just need to get an idea, but of course I'd also be thankful if you can refer me to all sorts of literature, specs, overviews, etc.
Thanks!
Click to expand...
Click to collapse
This thread is over 2 years old now. The original purpose was to try and find others interested in sharing the undocumented secrets of TI's FM chip.
But after my info dump, nobody showed up to share with me, and likely nobody will, so I will close it after this post.
Any further discussion about FM can move to the Spirit FM thread in my sig.
These chips put out tiny amounts of power in transmit mode, maybe 10-30 milliwatts or so. The only phones I have that transmit have to have their headset cable antenna wrapped around the receiver antenna to get anything resembling decent quality.
So I'd call the transmit radius a few centimetres at most. Little wonder then, perhaps, why so few Android devices support transmit.

Related

Overclocking

Inspired by GSLEON3 I have started to investigate overclocking options of the ARM11 (runs OS) and ARM9 (runs radio). I disovered a few things which may be of interest, but so far no spectacular results. There is more research needed and I hope people like anton tomov, cmonex, olipro and pof can help out.
Here is a summary of my findings for the ARM11:
- it normally runs on 384MHz which is equal to a masterclock of 768MHz divided by 2
- the ARM11 clockspeed is 768/N MHz where N is a frequency divider (N=1..16)
- i haven't found an option for clock stepping. (If anyone has a MSM7x00 datasheet please share it with me so this can be investigated)
- i found ARM11 clock control code both in oemsbl and spl. The latter is great as it allows to control clock from WM
- there are two commands in a mfg spl to set ARM11 clock speed and to test it: "freq n" (n=0..6) and "test"
- "freq 6" sets the fastest speed: 384MHz and testing with "test" results in 436ms on my kaiser (MSM7200). Would be nice if someone tests this on a MSM7201 based kaiser
- i reverse engineered the "freq" command and found a table at 0x8c00e230 with 5 entries for each speed setting. For "freq 6" the settings are:
Code:
384000 ; equal to clockspeed/1000
1 ; determines which master clock to use (value is either 0 or 1)
1 ; master clock divider-1 (increasing it leads to slower test speeds)
96000 ; some other clock derived from from master clock
3 ; divider-1 for deriving the 2nd clock
- i hot patched these values with the "mw" command (e.g. mw 8C00E2A8 1 6D600) but could not establish any better result with "test"
- setting the divider to 0 (actually means divide 768MHz by 1) caused the device to freeze
- i didn't do any benchmarking in WM
- i haven't investigated ARM9
Okay, enough for now. I hope this triggers more interest and research for this topic.
i am sure there is interest. I have pinged both Wizcode (anton tomov) and Immiersoft over the past few months. Both have been slow to respond, and both seem to be having issues finding any sort of documentation on the processor.
Here's hoping you make more progress
Jocky,
did you get any indication as to how they are handling the default clock?
Have you found any reference correlating to:
AYGSHELL.dll
OLEAUT32.dll
COREDLL.dll
I would think that the system would use them to report current status so that the current clock rate settings can be changed appropriately.
Most of the current scaling apps out there import their data from these three libraries, so I wonder if ther is within them some way to walk back to the actual processes.
Of course my hacking abilities are pretty much non-existent, but I do see that unfortunately a lot of the critical areas in the popular overclocking apps are encrypted. Have to see who can help me with that.
I might be a noob...but here's my thought:
1)The diamond runs on 528mhz
2)That same table/coding should be in the diamond ROM, except it should have more "steps" right?
Anyway, that's a noob's thoughts at 11pm. (past my bedtime for sure : )
bios
i figure that if the diamond can run at 528mhz(on a 900mah battery)with the same chipset as the kaiser why cant the kaiser run at 528mhz with little affect on battery life.
should be a matter of setting the clockspeed in the bios or the kaiser equivalent. it should be in the radio bootloader(i believe it runs first on kaisers) ipl, spl or something or other.
however my bubble was burst when i read that the diamonds processor was made in a 45nm die and the kaisers processor was made in a 60nm die.
but the only thing i know is that i dont know ****.
The acpu table you're talking about could be found in msm_clk.dll and in the Android GIT repo:
http://git.android.com/?p=linux-msm...66c5b4e4da45b9e2ed1104444555eecd49171;hb=HEAD
Note, the Android ACPU table is slightly different from the one for the Kaiser, so I assume it's the difference between either the 7200 and the 7201 or the 90nm and the 45nm variations. The Android one is also missing one or two of the lower frequencies.
Btw, for msm_clk.dll, it's 6-column table, and the Android one is 7-columns.
To get and set the acpu clock, I think there's a few calls in either clkregim.dll or TrsTai_extension.dll. I'm sure you can find it by looking at the EXPORTS table.
Slightly unfortunately, a lot of the meat behind these calls are now hidden behind ONC RPC calls in the Diamond dlls.
Someone with a 7201, please enter bootloader and type "test" and post the number in ms shown.
Thx for the hint about diamond spl, i'm checking that out. I can nicely test the diamond spl with the upcoming "FrankenKaiser SPL Loader".
Ah thx for the link NuShrike. Yes that is indeed the clockspeed table:
Code:
26 /*
27 * ACPU speed table
28 */
29 struct clkctl_acpu_speed acpu_freq_tbl[] = {
30 { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, 0},
31 { 61440, ACPU_PLL_0, 4, 3, 61440, 0, 0}, /* VDD assumed */
32 { 81920, ACPU_PLL_0, 4, 2, 40960, 1, 0}, /* VDD assumed */
33 { 96000, ACPU_PLL_1, 1, 7, 48000, 1, 0}, /* VDD assumed */
34 { 122880, ACPU_PLL_0, 4, 1, 61440, 1, 3},
35 { 128000, ACPU_PLL_1, 1, 5, 64000, 1, 3}, /* VDD assumed */
36 { 176000, ACPU_PLL_2, 2, 5, 88000, 1, 3}, /* VDD assumed */
37 { 192000, ACPU_PLL_1, 1, 3, 64000, 2, 3}, /* VDD assumed */
38 { 245760, ACPU_PLL_0, 4, 0, 81920, 2, 4},
39 { 256000, ACPU_PLL_1, 1, 2, 85333, 2, 5},
40 { 264000, ACPU_PLL_2, 2, 3, 88000, 2, 5}, /* VDD assumed */
41 { 352000, ACPU_PLL_2, 2, 2, 88000, 3, 5}, /* VDD assumed */
42 { 384000, ACPU_PLL_1, 1, 1, 128000, 2, 6},
43 { 528000, ACPU_PLL_2, 2, 1, 132000, 3, 6},
44 { 0, 0, 0, 0, 0, 0, 0},
45 };
108 struct clkctl_acpu_speed
109 {
110 unsigned int a11clk_khz;
111 int pll;
112 unsigned int a11clk_src_sel;
113 unsigned int a11clk_src_div;
114 unsigned int ahbclk_khz;
115 unsigned int ahbclk_div;
116 int vdd;
117 };
The main difference is the additional PLL clock source of 1056MHz called "ACPU_PLL_2"
I don't think we have that PLL in a standard Kaiser, but I will try to verify it with some experiments.
NuShrike: do you know whch clockspeed is set on a stock Kaiser? Can u patch Android and try to force 528000 ?
We're talking about two completely different CPUs here, the Kaiser CPU is built on a 90nm node process whereas the Diamond is built on a 65nm node process, the difference in power consumption and heat generation between the two is most likely the reason that all Diamonds can run at 528Mhz without fault... Tbh I think you're being optimistic to assume the Kaiser CPU can withstand that speed for any length of period, and also how are you going to test for stability? As far as I know Stress Prime is a windows only app! SOrry to put a dampener on the idea but I don't condone this...
eXceed said:
We're talking about two completely different CPUs here, the Kaiser CPU is built on a 90nm node process whereas the Diamond is built on a 65nm node process, the difference in power consumption and heat generation between the two is most likely the reason that all Diamonds can run at 528Mhz without fault... Tbh I think you're being optimistic to assume the Kaiser CPU can withstand that speed for any length of period, and also how are you going to test for stability? As far as I know Stress Prime is a windows only app! SOrry to put a dampener on the idea but I don't condone this...
Click to expand...
Click to collapse
Of course, but you see we're doing research and experiments and trying to find out details on how to control clockspeeds. There are very likely other PLLs in a stock Kaiser, not necessary running on 1056MHz, but perhaps 800 or 900MHz. To obtain useful results requires people with experience and persistance ...
Yes of course, sorry I didn't mean to completely force the idea out the window as such, but I don't want people to expect good results!
this needs to be made a sticky so that all can help with testing any way that they can. It would be amazing to have our Kaisers running faster from a simple change to the SPL and some .dll's (Well I am sure its not to easy) I will do what ever needs done for testing. Should be easy with the linux image compared to the WM6.1 OS. Am I correct on that?
austinsnyc said:
this needs to be made a sticky so that all can help with testing any way that they can. It would be amazing to have our Kaisers running faster from a simple change to the SPL and some .dll's (Well I am sure its not to easy) I will do what ever needs done for testing. Should be easy with the linux image compared to the WM6.1 OS. Am I correct on that?
Click to expand...
Click to collapse
agreed, need to make this a sticky, the msm 72xx/75xx platform looks like it is going to be around for a while. overclocking may be whats needed to get that last bit of performance out of our kaisers.
in any which case jocky, i am willing to flash a test spls' and or roms with modified dlls and what not.
have you tried playing around with "HTC Peformance"? aparently it overclocks the Titan/6800 and actually works. But i tried it on my kaiser and didnt notice any difference. ill upload it if your interested.
mikeeey said:
have you tried playing around with "HTC Peformance"? aparently it overclocks the Titan/6800 and actually works. But i tried it on my kaiser and didnt notice any difference. ill upload it if your interested.
Click to expand...
Click to collapse
that cab has been proven to do absolutely nothing.
We Should All Start Posting What We Have...
MSM7200
Has had FrankenKaiser.exe run on it before.
Kaiser got it like the week they came to nyc.
i have an at&t tilt.
MSM7200
security unlocked
Spl 1.0.olipof
Display driver 1.60.00.00
unbranded TyTN II
Spl 1.0.OliPof
with some mixing of drivers that partially work (but crashes every time i try something new)
Guys, please enter SPL tricolor, connect with MTTY and type "test" followed by return. Post the value it returns and also whether you have a MSM7200 or 7201. Test only works if you have HardSPL installed.
For reference: my msm7200 kaiser returns 436ms
AT&T Tilt
MSM7201
SPL-1.0.OliPof
test returns 436ms

[Q] ability to access WiFi 802.11 stack and radio headers?

Hi all,
I've been digging around to try and gain the ability to access the WiFi stack from an Android device that is rooted. What I am interested in, is capturing the 802.11 radio headers. I've done a bunch of searching, and it seems like getting the card in to promiscuous/monitor mode is out of the question. I haven't been able to find anyone to do it. But, even not being in this mode I am wondering if it is possible to get 802.11 headers.
I've downloaded the android-wifi-tether project to get the tools it has pre-built and installed on the file system, such as iwconfig, and I've also installed tcpdump.
I cannot get the card into monitor mode, as was expected:
Code:
# ./iwconfig tiwlan0 mode monitor
Error for wireless request "Set Mode" (8B06) :
SET failed on device tiwlan0 ; Operation not supported on transport endpoint.
That's fine. But when I use tcpdump, it seems as though the lowest layer of information available is the Ethernet/IP information:
Code:
# /data/tcpdump -i tiwlan0 -L
tcpdump: WARNING: can't create rx ring on packet socket 3: 92-Protocol not available
Data link types (use option -y to set):
DOCSIS (DOCSIS) (printing not supported)
EN10MB (Ethernet)
So for example, if I tcpdump:
Code:
07:51:21.793444 IP 192.168.1.103.34528 > 64.233.169.193.443: Flags [S], seq 3412091441, win 5840, options [mss 1460,sackOK,TS[|tcp]>
07:51:22.096239 IP 64.233.169.193.443 > 192.168.1.103.34528: Flags [S.], seq 513767123, ack 3412091442, win 5672, options [mss 1430,sackOK,TS[|tcp]>
Has anyone been able to dig any lower in the networking stack?
Thanks!
George
OK, I've done a significant amount of digging, and luckily the TI wl1271 wireless driver is built as a kernel module (I'm using a Droid 1). the "dmesg" output provides some hints that the TIWLAN module is active and parsing incoming packets at the lower layer:
Code:
<6>[ 5940.231292] TIWLAN: 3835.067243: rx , ERROR: rxData_receivePacketFromWlan() : MLME returned error
The code for this function can be found here, and even better the low-level packet information (e.g., RSSI) is available in this function.:
Code:
/*
* Set rx attributes
*/
RxAttr.channel = pRxParams->channel;
RxAttr.packetInfo = pRxParams->flags;
RxAttr.ePacketType= pRxParams->packet_class_tag;
RxAttr.Rate = appRate;
RxAttr.Rssi = pRxParams->rx_level;
RxAttr.SNR = pRxParams->rx_snr;
RxAttr.status = pRxParams->status & RX_DESC_STATUS_MASK;
I'm also wondering whether or not it might be possible to drop the card in to promiscuous mode with some driver hacking. It appears to be possible through the RX filter, albeit maybe not supported by the actual firmware (that would suck):
Code:
#define RX_CFG_PROMISCUOUS 0x0008 /* promiscuous - receives all valid frames */
#define RX_CFG_BSSID 0x0020 /* receives frames from any BSSID */
#define RX_CFG_MAC 0x0010 /* receives frames destined to any MAC address */
#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
I too want to capture WiFi packet headers on Android using tcpdump. I am using an HTC dream phone (Android 1.6, Wi-Fi (802.11b/g) using a Texas Instruments WL1251B chipset). The default TI driver filters the 802.11 packet headers while doing a packet capture on the device using tcpdump. Did you figure out a way to capture the 802.11 headers using the default TI driver?
Also, I was looking at installing a mac80211 based driver on an android device. I followed the instructions to create the kernel modules and loaded them up on the phone. But, I could not activate the WiFi interface after doing so (though I saw the "wlan0" interface indicating that the mac80211 driver was loaded).
So, I am stuck at this point. Can you provide some directions from here?
Thanks
Ashish

[DEV][TUTORIAL] How to poll GPIO values from Haret

In case you need to know how to poll GPIO values from photon, here is a small how-to:
First of all, read THIS:
http://htc-linux.org/wiki/index.php?title=HaRET_Documentation#Polling_GPIOs
To disable automatic launch of Android when you execute HarET, you must rename your file "startup.txt" to "default.txt"
The issue is, when you poll for GPIOs with Haret, you got a numeric value that does not match with GPIOs in Linux (board-photon.h)
To translate "HarET GPIO" to "Linux GPIO", here is a trick:
Haret gives you this line:
009.179 GPIOS 92f00808(117)=300100
Click to expand...
Click to collapse
Take the number between parenthesis: 117
Divide it by 32:
117/32 = 3, rest = 21
3 is the GPIO bank:
bank0 = 0 to 15
bank1 = 16 to 42
bank2 = 43 to 67
bank3 = 68 to 94
bank4 = 95 to 106
bank5 = 107 to 121
in our example, bank3 starts at value 68, so the Linux GPIO is:
68 + 21(rest of division) = 89
note: if the bank number is higher than 5, it means it is the following bank, or the one after. in this case, remove 6 or 12 to the bank number so you have a value between 0 and 5, and do the normal computation.
I must to say THANK YOU!
hmm I not understand (rest) I got 3,65625 (bank 3, rest 65626)
r0bin said:
117/32 = 3, rest = 21
Click to expand...
Click to collapse
Also next situation:
057.215 GPIOS 92f0083c(313)=61c8102
9,78125 (bank 9, rest 78125)
munjeni said:
hmm I not understand (rest) I got 3,65625 (bank 3, rest 65626)
Also next situation:
057.215 GPIOS 92f0083c(313)=61c8102
9,78125 (bank 9, rest 78125)
Click to expand...
Click to collapse
lol
on my sample, another way to say it:
117/32 = (3 * 32) + 21
or:
117/32 = 3.65625, you take the 3, rest 0.65625 * 32 = 21
in your case:
303/32 = 9.78125, you take the 9, rest 0.78125 * 32 = 25
9 is too big, remove 6 => it's bank3
bank3 = 68+25 = 93
in board-photon.h, it is defined like:
LIBERTY_GPIO_LS_EN 93
in the code (board-photon.c) it seems it's the GPIO for power
thanks, understand now \o/
Hi,
I got slightly different format for GPIOS.
Please refer to here
http://pastebin.com/xr4p3cd8
How to I convert them?
Thanks in advance

Big Bang steering wheel interface support page

Support Page for the Big Bang Steering Wheel Interface
The purpose of this page is to provide support and answers to questions for the Big Bang Steering Wheel interface until our Wiki and support site at UnderGroundElectronics.net is finished.
We are discussing the Big Bang Steering Wheel interface project on Kickstarter.
A Quick Description: The Big Bang is a interface between the car and your tablet. Our goal is to enable you to install your tablet in your car with OEM like integration. We had to start somewhere and we are planning other items for the future but this critical first step we felt was the most nessasary thing for a every day user experiance.
We know that there are a lot of people and threads on installing tablets in cars. We've seen various methods to achieve this solution but no one has made a item for this specific purpose. Even if your car does not have steering wheel controls, this device allows for the waking and sleeping of the tablet while still allowing it to charge constantly.
This device is fairly simple in operation, however the automobiles they go in are not so simple. There are lot of things that can cause problems and we hope to address them here (until we can get our site up, and maybe even after since XDA is a go to place for trouble shooting problems with our tablets and phones).
Lets Start with a basic description of operation
Most autos that have steering wheel controls use a single wire behind the head unit. This wire is typically one of three types: Resistive Negative, Resistive Positive, and Digital. A few Autos use independent wires, one example is Harley Davison. Each button is independent and thus must use resisters to combine the buttons to a single wire.
Currently the Big Bang is made to work on Negative and positive resistive Autos. Data type is expected to be developed by the time we ship.
Finding the wire in your auto:
At the steering column is the best way. But BE WARNED, there is danger probing around with the electrical system of any car that has airbags. You should disconnect the battery and let the car sit at least 30 minutes before doing anything with the wiring in a car with air bags. (Yes we realize that this is very cautious stand but we don't want people getting hurt. If you are un-experienced with Automotive electrical or unsure of what you are doing you probably should consult you local Car Stereo Shop. At the very least use sites like "the 12volt .com" or ask for assistance here. AND NEVER EVER USE A TEST LIGHT, Voltmeters only here.
We can't stress this enough. The data systems and air bag systems in modern cars are very sensitive and can be damaged or set off with just static electricity. We can not be held responsible for what you are doing, we are simply trying to guide you. In my case I have years of car audio experience. I still run into things in new cars that I've never seen before and I've seen plenty of cars damaged by people cutting the wire that was the right color or "injecting voltage" to test something.
Moving forward:
Negative systems:
Typically a Negative system is one that the control wire will go negative from a resting position that is positive. In the case of most Honda's it rests at 5V and goes negative with each button. If you have a stock navigation system (In the case of the Honda. Others may be different) some buttons may be dedicated to the Nav Brain. That unit needs to be removed with the head unit to function properly and has special "reverse wiring" to provide all buttons functions.
Positive systems
Positive systems work just like negative systems but instead rest at or near ground (zero voltage). The voltage at the wire will go positive when a button is pressed.
Programming the Big Bang
Our site will cover most of this but at present the Big Bang is programmed via a PC. We do hope to one day be able to program it from the tablet, allowing one to tweak the controls after install and to improve installation experience. We will provide more detailed instructions closer to launch day but the short of it is you will download a program, modify it to fit your car/application then run it to program the Big Bang.
Connecting the Big Bang
We recommend using the Big Bang with a USB Hub that is powered. We have found some 12V to 5V dc to dc Converters we will link below as well as the USB hubs we recommend. The Big Bang will connect to the USB hub and the USB hub will plug into the tablet or phone. The big bang will have two wires that need to be connected. The Big Bang is powered from the USB power, so it and the tablet are always receiving power. It will have two wires to be connected. The white wire is the control wire and needs to be attached to the steering wheel control wire. The Red one is the ACC[essory] or IGN[ition] wire and needs to be tapped to it as a reference for the cars voltage. This wire should be fused as there is always a potential for shorting. It may be redundant but we still recommend fusing this wire independent of others, or using the same fuse used for the USB 12v to 5v converter.
Problems we've seen in our testing
First and worst problem I've experienced is cheap USB OTG cables. Some are very finicky about the position the sit in to make contact. It could be that they are old and worn out too. We plan to explain a "best methods" guide but best I can say is get decent quality USB OTG adapters for this use.
The second issue I've seen is random reboots. My n7 experiences these only when I'm using it in the car. I'm running Paranoid Android, and I don't believe it is the issue. I believe it is due to the faulty USB cable described above.
Other then that, we've experienced few issues but we are still in somewhat early testing phase.
I'll update this post with Q and A's as they come in. When asking questions about your installation it would be helpful for you to be as thorough as possible. Let us know if you are an experienced car audio person or not. Also make model and year of car may be important.
Until now this has been our idea for our car, we now open it to you. We can't promises anything but if you have suggestions, tell us. We may include the feature. We are working on other products as well to enable people to install their tablet and have it operate as normal as possible.
Tested Devices:
We've tested it on these devices so far but you can help. Get a USB OTG cable for your tablet, then plug in a USB keyboard or mouse and see if it functions. post your results and we'll add it to the list.
Confirmed working:
N10
N7
Galaxy Note2
Galaxy S3
Know to NOT work:
N4
Post #2
So we have run into a problem with the USB OnTheGo mode and charging. The Big Bang requires the tablet to be in USB OTG to receive control inputs. While in USB OTG mode the tablet is not charging. We have found there is another mode, Rid_a mode. By enabling this Rid_a mode the tablet will do both USB OTG and charge. We have it working on some Samsung's, we now need to figure out the nexus line.
It is possible that this is something coded into the kernel so we are looking into that. Right now the two default options, if we can't work it out, are:
A) A source built kernel with this one thing enabled.
B) a much more complicated setup that would auto switch between host and client mode from the ignition control. This we feel is less desirable based off the fact that if one is driving long distances the tablet could die out.
Post #3
Ok, I know I’m a bad person, I have left you hanging for ages. Well, it was not without feeling bad, and it was not on purpose, I’ve just been busy trying to pay bills.
So I suppose I’ll start with an overview. So our prototype is a DigiSpark. You can get one for like $9.99 or less. They are neat little devices. If your cool you can follow this little how to to use the Atiny85 http://youtu.be/30rPt802n1k, Which is where we were going with our own custom board. You might need to understand a little about voltage, voltage dividers and such. I will try to help, but I can’t climb in your car and measure the voltage or resistance for you so you’ll need to know how to use a DVOM and some pretty basic electronics.
Ok so probably the most common steering wheel interface type is a negative type, but there is other types. So for the standard type, I’ll try to diagram This is pure example.
Code:
(-gnd)----|---/\/\/\/\/\-----(s1)--------|
| 12k R1 |
|---/\/\/\/\/\-----(s2)--------|
| 8k R2 |
|---/\/\/\/\/\----(s3)---------|
| 5k R3 |
|---/\/\/\/\/\----(s4)---------|
| 2.4k R4 |
|---/\/\/\/\/\----(s5)---------|
| 1k R5 |
|---/\/\/\/\/\----(s6)---------|
450 R6 |
|---------/\/\/\/\/\---- (+12v (vcc) )
| 1k Rb
|
\ /
\/
MPU pin ?
So basically the way this works is on the steering wheel side the wire is grounded. In my honda there is actually both wire sides, the positive and negative or common resistor/common Switch sides. Since I pulled all of the stock Nav Electronics out, I had to ground the one side and put the 12v through the other. You can find a lot of this info out from PIE, PAC and peripheral websites (They make steering wheel interfaces and they should have some info in the installation manual PDF on what your car will be).
This may not be new to you, but for others: The Math is
R1+Rb
--------- * V (probably 12v, 14.4v running)
R1*Rb
So for each switch we’ll have a voltage, or more specifically a voltage range. I had a bit of a solution for the range part but for most applications having a range will be acceptable. In my case the range was +(-) 0.5v.
This should give you approximately something like S1= 11v to 12v, S2= 8v to 9v, etc
So the problem is we can only use a 0v to 5v range. So either we must adjust Rb or use another solution, such as an OP Amp to reduce the voltages. However it should be enough to adjust the resistance of Rb.
So we are going to use the A/D input pin of the ATtiny85 (digispark). We’ll convert that to a digital number and then compare it to some reference values. We’ll just consider the MSB Most significant bits and ignore the last few. This gives us some range to tolerate voltage fluctuations due to the cars electrical system.
That basically explains the car interface. We can do all kinds of neat stuff. We have a few useable pins so we can add pins for ACC, or door triggers, etc.
Now we need to consider the USB interface. The Digispark makes this easy. It is built on a board that has a USB interface built in. If you are using the ATtiny85 on a DIY you’ll need to make up a USB cable for this part. We’re going to make the steering wheel control look like a USB keyboard or Audio control to the tablet.
For the USB part I found a neat description on XDA in a reply on a post that inspired the basic workings. Understanding the USB ASCii code is important here. Android uses many standard ones. It’s a complicated code as it is meant to be able to grow and handle all kinds of different possible things.
The Main uses I found were in the Standard keyboard codes and in the Audio control codes.
We use the Digispark hex program that comes in the digispark start up guide, keyboard.h . We pass the code calls to keyboard.h and it does the rest, except we need to add our specific functions to keyboard.h.
We’ll modify keyboard.h and write our sketch and program the Arduino/Digispark/ATtiny85. It will loop through reading the A/D and comparing to the pre-determined reference values. When it matches we’ll output a USB code to do something on the tablet.
This is where the problem came in. Of all things I didn’t expect to have a issue charging while acting as a usb host to, effectively, a keyboard. As of USB standard 1.1 using a certain resistance between the two data pins will put it in different modes. Unfortunately what I found was on some Samsung devices this value put it in a different mode, and yet a mode that gave us USB host, didn’t allow for charging. On the Nexus devices I couldn’t find a way at all, without requiring a different kernel to be installed. This left two main choices. A) charge when the car is off only. Which is unacceptable in my opinion. A long drive would kill even a Nexus7 and then you’re stuck with nothing. B) Require an aftermarket kernel/ROM installed. Well we realized guiding one to remove the deck and do some major work to put a tablet in the dash ment they were serious, it didn’t seem fair to expect them to also root/hack the OS on said device. Sure I suppose we could have made it such but it didn’t fit our goal. There is a third option I just now thought of. One could add a circuit that triggered the Host mode change only when the buttons are pressed. This can be as simple as causing a closed/open connection between data+ and data- . This could cause some missed keystrokes but if planned right, it might be a viable solution.
Sketch Code:
Code:
#include "DigiKeyboard.h"
/*
Basic Steering wheel to Tablet (or any computer) controls. Posted here are the basics from a honda ridgeline '07. The steering wheel wire is Green with red stripe, pin 3
The Brown wire, pin 11, Needs to be connected to ground (the buttons are resisters accross those two). This is only Vol+,Vol-, Mode, Ch+, Ch-. I will search for Back and Talk later.
The Resistance Values read from it was: Rest=9.9k, Mode=3.73k, Ch+= 1.69k, Ch-= 780, Vol+=356.8, Vol-=101.4. Using a 1k pull up to the 5V USB lead seems like a good value and will yeild
a large variance in voltage output. The outputs should be Rest=4.5454v, Mode=3.94v, Ch+=3.146v, Ch-=2.19v, Vol+=1.314v, Vol-=.4603v. These can be converted to a 10bit value and are about
Rest=931.4, Mode=807.4, Ch+=644.6, Ch-=448.8, Vol+=269.26, Vol-=94.3. This variance is more then 100 dec thus to allow a wide tolarance we will drop the last four bits and
test only the four MSB. I.E. if analogRead(0)==11010000 then Ch+. The LSB will need to be striped away due to them not being exactly the same otherwise.
Grey wire, at steering coulumb is the Talk and Back button. It works with The Same brown wire as with the volume. 9.99k at rest, Talk= 2.238K, Back= .64k. Used with a 1K resister, They are
Rest=4.5454v, Talk=3.455v, Back=1.95v.
## DISCOVERY, analogRead is a DEC value and is difficult to convert. was going to read value then roll value right and then compare. This would have given a range:
// audioState = audioState >> 7;
// navState = navState >> 7;
##Delay output can act as a Remote turn on for Amplifire.
*/
/* Rest= 931 = 1110100011 = 0x3A3
// Mode=807 = 1100100111 = 0x327
// Ch+=644 = 1010000100 = 0x284
// Ch-=449 = 0111000001 = 0x1C1
// Vol+=269 = 0100001101 = 0x10D
// Vol-=94 = 0001011110 = 0x5E
//
// Rest= 931 = 1110100011 = 0x3A3
// Talk= 708 = 1011000100 = 0x2C4
// Back= 399.6= 0110010000 = 0x190
*/
//const int audioCtrl = 5; //pin 5, analog Read 0
//const int navCtrl = 2; //pin 2, analog Read 1
const int ledPin = 1;
int audioState = 1023; //B1110100011; //Variable to store button Value
int navState = 1023; //B1110100011; //Variable to store button Value
int twiceSel = 0; //Variable for checking for double press of vol- and of back
int storeState = 0; //Store the current state for double press check.
void setup() {
pinMode(ledPin, OUTPUT); // Turn on onboard LED when button is pressed
// pinMode(audioCtrl, INPUT); //P0 is volume up
// digitalWrite(volUp, HIGH); //set the pull up resister
// pinMode(navCtrl, INPUT); //P2 is Volume down
// digitalWrite(volDown, HIGH); //set the pull up resister
}
void loop() {
DigiKeyboard.update();
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
audioState = analogRead(1); //read value at audio control pin2, write it to audioState for further processing
navState = analogRead(0); //Read the value of navagation Control pin5, write it to navagationState for further processing.
// Rest= 931 = 1110100011 = 0x3A3 = 111
// Mode=807 = 1100100111 = 0x327 = 110 >675 <850
// Ch+=644 = 1010000100 = 0x284 = 101 >550 <675
// Ch-=449 = 0111000001 = 0x1C1 = 011 >300 < 500
// Vol+=269 = 0100001101 = 0x10D = 010 >120 < 300
// Vol-=94 = 0001011110 = 0x5E = 000 >50 <110
//
// Rest= 931 = 1110100011 = 0x3A3 = 111
// Talk= 708 = 1011000100 = 0x2C4 = 101 >650 <750
// Back= 399.6= 0110010000 = 0x190 = 011 >350 <450
// TODO:
//Need debounce, or slowdown, or delay. Currently it cycles too fast.
// Add double press Vol- triggers mute
// Add double press Back triggers Home
//Fix the "/" causing search to display "//
// Use Dpad instead of arrow (probably a function of the Keypad arrows)
if (audioState >675 && audioState < 850 ) { //Mode inbetween 675 and 850
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_ENTER); //tell computer Select
digitalWrite(ledPin,LOW);
delay (200); //200ms Delay
}
else if (audioState >550 && audioState < 675) { //Ch+ >550 < 675
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_ARROW_RIGHT); //tell computer Right Arrow
digitalWrite(ledPin,LOW);
delay (200); //200ms Delay
}
else if (audioState >300 && audioState < 500) { //Ch- >300 < 500
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT); //tell computer Left Arrow
digitalWrite(ledPin,LOW);
delay (200); //200ms Delay
}
else if (audioState >120 && audioState < 300) { //Vol+ >120 <300
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_VOL_UP); //tell computer Volume Up
digitalWrite(ledPin,LOW);
delay (200); //200ms Delay
}
else if (audioState >50 && audioState < 110) { //Vol- >50 < 110
delay (200);
for(int x =0; x < 5; x++) {
audioState = analogRead(1); //read button again
if(audioState >50 && audioState < 110){
digitalWrite(ledPin, HIGH);
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_VOL_DOWN); //tell computer Select
digitalWrite(ledPin,LOW);
//if statement test for 5cycle if button pressed again, if not changes vol- if so mutes
}
else if (navState >675 && navState < 850) { //Talk >650<750
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_SEARCH); //tell computer Select
digitalWrite(ledPin,LOW);
delay (200); //200ms Delay
}
else if (navState >350 && navState < 450) { //Back >350 <450
//if statement test for 5cycle if button pressed again, if not back, if so home
// storeState = 0; //Clear storeage
// twiceSel = 0;
// storeState = navState; // back was pressed, we need to store it's current state.
// navState = 0;
delay (200);
for (int x=0; x < 5; x++){ // Test 5 times
navState = analogRead(0); //Read the value of navagation Control pin5, write it to navagationState for further processing
if (navState >350 && navState < 450) { //Back >350 <450
// twiceSel = 1; //pressed twice
//Something different
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_HOME); //tell computer Select
digitalWrite(ledPin,LOW);
}
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_ESC); //tell computer Select
digitalWrite(ledPin,LOW);
}
}
}
/*
OLD code left for Refrence
buttonState = digitalRead(volUp);
if (buttonState == LOW) {
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_VOL_UP); //tell computer to turn the volume down
}
else{
digitalWrite(ledPin, LOW);
}
buttonState = digitalRead(volDown);
if (buttonState == LOW) {
digitalWrite(ledPin, HIGH);
DigiKeyboard.sendKeyStroke(0); //this is generally not necessary but with some older systems it seems to prevent missing the first character after a delay
DigiKeyboard.sendKeyStroke(KEY_VOL_DOWN); //tell computer to turn the volume down
}
else{
digitalWrite(ledPin, LOW);
}
*/
Keyboard.h Code:
Code:
/*
* Based on Obdev's AVRUSB code and under the same license.
*
* TODO: Make a proper file header. :)
* Modified for Digispark by Digistump
*/
#ifndef __DigiKeyboard_h__
#define __DigiKeyboard_h__
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <string.h>
#include "usbdrv.h"
// TODO: Work around Arduino 12 issues better.
//#include <WConstants.h>
//#undef int()
typedef uint8_t byte;
#define BUFFER_SIZE 2 // Minimum of 2: 1 for modifiers + 1 for keystroke
static uchar idleRate; // in 4 ms units
/* We use a simplifed keyboard report descriptor which does not support the
* boot protocol. We don't allow setting status LEDs and but we do allow
* simultaneous key presses.
* The report descriptor has been created with usb.org's "HID Descriptor Tool"
* which can be downloaded from http://www.usb.org/developers/hidpage/.
* Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted
* for the second INPUT item.
*/
PROGMEM char usbHidReportDescriptor[39] = { //USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
0x05, 0x01, // 0x05, 0x01 USAGE_PAGE (Generic Desktop)
0x09, 0x01, // 0x09, 0x06 USAGE (Keyboard)
0xa1, 0x01, // 0xa1, 0x01 COLLECTION (Application)
0x25, 0x01,
0x15, 0x00,
0x75, 0x01,
0x95, 0x05, // REPORT_COUNT (5)
0x09, 0xb5, // USAGE (Scan Next Track)
0x09, 0xb6, // USAGE (Scan Previous Track)
0x09, 0xb7, // USAGE (Stop)
0x09, 0xcd, // USAGE (Play/Pause)
0x09, 0xe2, // USAGE (Mute)
0x81, 0x06, // INPUT (Data,Var,Rel) - relative inputs
// -------------------- volume up/down bits
0x95, 0x02, // REPORT_COUNT (2)
0x09, 0xe9, // USAGE (Volume Up)
0x09, 0xea, // USAGE (Volume Down)
0x81, 0x02, // INPUT (Data,Var,Abs) - absolute inputs
// -------------------- padding bit
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
//0x05, 0x07, // 0x05, 0x07 USAGE_PAGE (Keyboard) change to 0x0c for consumer device.
//0x19, 0xe0, // 0x19, 0xe0 USAGE_MINIMUM (Keyboard LeftControl)
//0x29, 0xe7, // 0x29, 0xe7 USAGE_MAXIMUM (Keyboard Right GUI)
//0x15, 0x00, // 0x15, 0x00 LOGICAL_MINIMUM (0)
//0x25, 0x01, // 0x25, 0x01 LOGICAL_MAXIMUM (1)
//0x75, 0x01, // 0x75, 0x01 REPORT_SIZE (1)
//0x95, 0x08, // 0x95, 0x08 REPORT_COUNT (8)
//0x81, 0x02, // 0x81, 0x02 INPUT (Data,Var,Abs)
//0x95, 0x01, // 0x95, 0x01 REPORT_COUNT (simultaneous keystrokes)
//0x75, 0x08, // 0x75, 0x08 REPORT_SIZE (8)
//0x25, 0xE7, // 0x25, 0xE7 LOGICAL_MAXIMUM (130) 0x65 originally
//0x19, 0x00, // 0x19, 0x00 USAGE_MINIMUM (Reserved (no event indicated))
//0x29, 0xE7, // 0x29, 0xE7 USAGE_MAXIMUM (Keyboard Application) 0x65 originally
//0x81, 0x00, // 0x81, 0x00 INPUT (Data,Ary,Abs)
0xc0 // 0xc0 END_COLLECTION
};
/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter
* 10 Keyboard/Keypad Page for more codes.
*/
/*
#define MOD_CONTROL_LEFT (1<<0)
#define MOD_SHIFT_LEFT (1<<1)
#define MOD_ALT_LEFT (1<<2)
#define MOD_GUI_LEFT (1<<3)
#define MOD_CONTROL_RIGHT (1<<4)
#define MOD_SHIFT_RIGHT (1<<5)
#define MOD_ALT_RIGHT (1<<6)
#define MOD_GUI_RIGHT (1<<7)
//#define KEY_ARROW_UP 0x52 //Added 2-5-2013 JWA
//#define KEY_ARROW_DOWN 0x51 //Added 2-5-2013 JWA
*/
//Tested with Logitech keyboard on N7. Right Meta key (MOD_GUI_RIGHT) plus F1 = home. Right Meta plus F3= search. Home = Internet home, Search = Windows search Application specific according to Logitech page.
#define KEY_HOME 157 //Added 2-7-2013 JWA according to android doc 3, According to other doc 165
#define KEY_MUTE 0xE9 //Added 2-7-2013 JWA keypad 3 and Page down according to android doc 91/127
#define KEY_SEARCH 127 //Added 2-6-2013 JWA according to android doc 84
#define KEY_ESC 41 //Added 2-6-2013 JWA KEboard ID ESC = 41
// /system/usr/keylayout/geniric.kl
// 172=Home
// 217= Search - 127
// 213== Music
// 140== Calculator
// 158 = Back - 1
// 102=power Confirmed hid usage ID
// 101=menu confirmed
#define KEY_ARROW_LEFT 0x50 // Android dock d-pad left = 105
#define KEY_ARROW_RIGHT 0x4F //Added 2-5-2013 JWA Andorid dock D-pad right=106
#define KEY_ENTER 40 //mode long press could do recent apps key 187
#define KEY_VOL_UP 128 //Added 2-5-2013 JWA 0x80 Andoid dock volume up=115 vdown= 114
#define KEY_VOL_DOWN 129//Added 2-5-2013 JWA 0x81
class DigiKeyboardDevice {
public:
DigiKeyboardDevice () {
TIMSK &= !(1<TOIE0);
cli();
usbDeviceDisconnect();
_delay_ms(250);
usbDeviceConnect();
usbInit();
sei();
// TODO: Remove the next two lines once we fix
// missing first keystroke bug properly.
memset(reportBuffer, 0, sizeof(reportBuffer));
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
void update() {
usbPoll();
}
void sendKeyStroke(byte keyStroke) {
sendKeyStroke(keyStroke, 0);
}
void sendKeyStroke(byte keyStroke, byte modifiers) {
while (!usbInterruptIsReady()) {
// Note: We wait until we can send keystroke
// so we know the previous keystroke was
// sent.
usbPoll();
_delay_ms(5);
}
memset(reportBuffer, 0, sizeof(reportBuffer));
reportBuffer[0] = modifiers;
reportBuffer[1] = keyStroke;
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
while (!usbInterruptIsReady()) {
// Note: We wait until we can send keystroke
// so we know the previous keystroke was
// sent.
usbPoll();
_delay_ms(5);
}
// This stops endlessly repeating keystrokes:
memset(reportBuffer, 0, sizeof(reportBuffer));
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
//private: TODO: Make friend?
uchar reportBuffer[2]; // buffer for HID reports [ 1 modifier byte + (len-1) key strokes]
};
DigiKeyboardDevice DigiKeyboard = DigiKeyboardDevice();
#ifdef __cplusplus
extern "C"{
#endif
// USB_PUBLIC uchar usbFunctionSetup
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (usbRequest_t *)((void *)data);
usbMsgPtr = DigiKeyboard.reportBuffer; //
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){
/* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT){
/* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* we only have one report type, so don't look at wValue */
// TODO: Ensure it's okay not to return anything here?
return 0;
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
// usbMsgPtr = &idleRate;
// return 1;
return 0;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
}
}else{
/* no vendor specific requests implemented */
}
return 0;
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __DigiKeyboard_h__
I had planned and some idea of how to implement things like double press vs long press vs single short press all without lots of delay. It had to do with using changes in the AD values to trigger events and use timers to allow other things to happen in the meantime. Also things such as two buttons pressed at the same time could potentially trigger an event.
Unfortunately I’ve abandoned this whole thing. Firstly I have a background in Car audio, so unlike many of you, I am used to a gaping hole in my dash. My stereo is in a state of flux while I come up with exactly what I want to do. Right now I enjoy just popping my Note2 on the dash and using it for my nav/music needs it allows me to keep my tablet in the house. I’m not saying the idea isn’t still great, nor that I don’t love it. If I was in Car Audio still, I would be using Nexus7’s in place of Alpine car stereos all day long.
Links:
http://www.Digistump.com buy your digispark here, Also the source of much of the code, software and info for making things work.
http://www.arduino.cc/ you’ll need the software, bare minimum. The Digispark page may walk you through installing it.
http://www.atmel.com/Images/Atmel-2...ller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf The chip used in this project is based on the ATtiny85. One can use an Arduino if they choose.
https://github.com/digistump/Digisp...er/libraries/DigisparkKeyboard/DigiKeyboard.h Bluebie’s Keyboard.h library.
https://github.com/Bluebie/micronucleus-t85 Bluebie’s bootloader which provides the USB funcitonality
http://www.obdev.at/products/vusb/index.html More info on using an AVR as a USB device
http://www.microchip.com/forums/m618147.aspx Use of a PIC microchip as a USB device
http://www.microchip.com/forums/m440956-print.aspx HID Audio Controler Usage table
http://www.freebsddiary.org/APC/usb_hid_usages.php USB Useage tables.
http://www.usb.org/developers/devclass_docs/Hut1_11.pdf More USB useage tables
http://forum.xda-developers.com/showthread.php?p=36930621 Tunner app for USB FM radio
https://droidperception.wordpress.com/2013/01/13/nexus-7-webcam-attached-update/ Info on using Extrernal USB Webcams
http://forum.xda-developers.com/showthread.php?t=2113259 A great thread on what can be done with a tablet in the car. He beat me to the install by just a month or two. He also was the reason I realized the limitation on the Charging while acting as a host.
Much of the code above is not my work. I made changes to it where I needed to but, specifically in the keybaord.h almost all of it is not mine. Credit goes to Bluebie and/or Digispark for the original work. If they would like me to remove the code, Please ask, I will. However since it's posted on Github I believe it's safe to post here.
I'm working on a way to adapted steering wheel controls on my mustang. But the issue is I have a base with no controls. I want swap out a premuim steering wheel to get this, but I have to have fords flash the acm for it to work. The issue is I still wont have controls for the tablet since mt car does not have bluetooth. So it will become costly. My solution is to use arduino or some other way to communicate with the factory HU. So im looking forward to this as a viable option.
Just an FYI, CM10-based kernel allows USB OTG and charging at the same time.
I've been on this hunt for a couple months now, albeit not hardcore. I have a rooted Galaxy Tab 2 7.0 that I'll be installing into an Infiniti G35. I would be more than happy to test stuff out for you if you want another guinea pig.
Pics to come
I'll post some pics from my installation so you can get an idea of what I did. Hopefully that and the code, etc will help you figure out how to do yours.
So hopefully Posting this will help some people get their own going. Here are the photos from the unit in my car.
My car has two sets of controls, first is the volume and channel buttons, second is the talk and navigate buttons. Also because I removed the complete Nav system the whole circuit was open. This gave me more options on how to do it, but I wen't with the more conventional. The Orange wire is going to ground. The Red and Yellow are each set of controls. The 1K resistors is a pull up resistor sourced from Vin on the digispark.
Hey joeavery2
thanks a lot for the hard work
If I am understanding the connections correctly, the tablet will draw the charge power from the USB Hub correct? If this is the case, is the tablet limited to 500mA charge current?
Hi guys i would ask your help. I have an Alfa Romeo Giulietta, Installed in the dash a nexus 7 2013 and I want use the steering wheel buttons. The car use the protocol is 15765-4 29bit and I have on Bluetooth obd reader. Can you please help me out? Thanks in advance.
Inviato dal mio FRD-L09 utilizzando Tapatalk

[KERNEL] mainlining Manta kernel

Hi,
I'm trying to port kernel 5.x to the Manta device (Nexus 10). The architecture is arm and the soc is exynos5250. I have no problem with drivers support because there are few similar devices already supported in mainline.
Therfore I started a write a device tree and tried to boot it. Nothing happened. Screens stays blank and device seems to be dead.
I'm looking for ideas. I tried a lot of things already . It's very strange because I would have expected a kernel panic and a reboot. It does nothing at all.
Of course I don't have a serial link. For now I use a small ramdisk image that just reboot the system after a 20 seconds sleep.
I'm wondering if there not a compatibility problem with the old bootloader. Please note that I append the dtb to the zImage and I activated the DTB-ATAGS compatibility options.
I fixed the decompressed kernel address (zreladdr) because the default calculation couldn't work.
I was thinking that my kernel image was a bit too big : I increased the original kernel size using zeroed padding and this one still works very well with my ramdisk.
So I'm a bit confused and I don't really know what I could check right now.
Here is the repo : https://github.com/jmarcgit/manta-mainline
You can find there the current dts and the config file I'm 'using.
I'm merging the default exynos config file with mine therefore it discards a lot of useless options in order to reduce the kernel size and does very few adaptations.
Thanks a lot for your support
Hi,
Happy to see that I'm not the only one trying to accomplish that!
I am not surprised that your reboot script does not work. On my config, the kernel boots without panic, but any call to a sleep/wait function freezes the system. Hence you may want to try to reboot the system without delay.
I cannot remember any compatibility issue with the bootloader.
Please note that you can get a serial link using the audio jack, see here: https://wiki.postmarketos.org/wiki/Serial_debugging:Cable_schematics#Nexus_debug_cable
Then you will have to enable low-level serial (I don't remember the exact name of the kernel option) on TTYSAC2. This has been immensely helpful on my side. Be careful though, as manta uses 1.8V UART.
I will fork your repo to put my config and dts in there as soon as I get some time, so that we can hopefully share, compare and improve our respective progress.
As a follow-up, I ran your configuration on my Manta (I only made the changes to get the serial console and added a missing fixed-clock node in the DTS that made the kernel panic in an early stage, see my fork here https://github.com/alexmrqt/manta-mainline/tree/8bf3528c1f9d9fb5eeb478901a88c495cacf5247).
With that, the device reboots after some times (but it is due to a kernel issue, as I used another ramdisk that is not supposed to do that).
See the kernel console below.
Code:
Starting kernel at 0x40008000...
AST_POWERON..
DEVICEINFO;R32D2042RBF;MANTAMF01;8;08:D4:2B:1F:C7:06;08:D4:2B:1F:C7:05;INFODONE
DTB:0x4021CC48 (0x0000A06D)
C:0x400080E0-0x40226E00->0x40682800-0x408A1520
DTB:0x40897368 (0x0000A1AB)
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 5.16.0-rc5-next-20211215 ([email protected]) (armv7-alpine-linux-musleabihf-gcc (Alpine 11.2.1_git20220219) 11.2.1 2022022
CPU: ARMv7 Processor [410fc0f4] revision 4 (ARMv7), cr=10c5387d
CPU: div instructions available: patching division code
CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
OF: fdt: Machine model: Samsung Nexus 10 (manta)
printk: bootconsole [earlycon0] enabled
Memory policy: Data cache writealloc
Samsung CPU ID: 0x43520210
Zone ranges:
Normal [mem 0x0000000040000000-0x000000004fffffff]
HighMem empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000040000000-0x000000004fffffff]
Initmem setup node 0 [mem 0x0000000040000000-0x000000004fffffff]
percpu: Embedded 9 pages/cpu s13136 r0 d23728 u36864
Built 1 zonelists, mobility grouping on. Total pages: 65024
Kernel command line: earlyprintk mem=256M console=ttySAC2,115200n8 PMOS_NO_OUTPUT_REDIRECT s3cfb.bootloaderfb=0x60000000 androidboot5
Unknown kernel command line parameters "PMOS_NO_OUTPUT_REDIRECT", will be passed to user space.
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes, linear)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 249628K/262144K available (3072K kernel code, 519K rwdata, 896K rodata, 1024K init, 207K bss, 12516K reserved, 0K cma-reserve)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
rcu: Preemptible hierarchical RCU implementation.
rcu: RCU event tracing is enabled.
Trampoline variant of Tasks RCU enabled.
rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
random: get_random_bytes called from start_kernel+0x374/0x5e4 with crng_init=0
Exynos5250: clock setup completed, armclk=1000000000
Switching to timer-based delay loop, resolution 41ns
clocksource: mct-frc: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
genirq: irq_chip COMBINER did not update eff. affinity mask of irq 57
arch_timer: cp15 timer(s) running at 24.00MHz (virt).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns
sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns
Ignoring duplicate/late registration of read_current_timer delay
Console: colour dummy device 80x30
Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
CPU: Testing write buffer coherency: ok
CPU0: Spectre v2: firmware did not set auxiliary control register IBE bit, system vulnerable
/cpus/[email protected] missing clock-frequency property
/cpus/[email protected] missing clock-frequency property
CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
cblist_init_generic: Setting adjustable number of callback queues.
cblist_init_generic: Setting shift to 1 and lim to 1.
Setting up static identity map for 0x40100000 - 0x40100060
rcu: Hierarchical SRCU implementation.
smp: Bringing up secondary CPUs ...
CPU1: failed to boot: -110
smp: Brought up 1 node, 1 CPU
SMP: Total of 1 processors activated (48.00 BogoMIPS).
CPU: All CPU(s) started in SVC mode.
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911
Hi Alex,
you did a great step forward ! I definately missed the serial cable.
Do you still work on it ? I think we are close to get it stable now.
Hi Marc,
Yes, I still work on it from time to time.
I got some nice progress since my last post:
- All CPUs now boot (a secure-firmware node was missing)
- WiFi now works
- Access to MMC partitions now works
- USB gadget works, but only when booting via fastboot (which suggests that something prevents the kernel to properly initialize the chip).
No luck getting the display to work so far
I just updated my repo with the last DTS and defconfig I use.
FYI, I do my tests with postmarketos (which allows me to test "advanced" features such as WiFi).
Hi Alex,
that's really great progress...
Does the backlight work ?
I don't have much time now.
Hi Marc,
Good news, I got the screen to work (as well as other things: battery, USB, touchscreen).
The bad news is that it requires some patches to the kernel code.
I included the patches (generated against kernel 6.1.4 from kernel.org) in the "patch" folder here - > https://github.com/alexmrqt/manta-mainline/tree/f4c38a7867f4e0e7481b71f96a0d0b4116b41c0f

Categories

Resources