2014年10月31日金曜日
SwitchCompat の inflate でエラー: android.view.InflateException: Binary XML file line #147: Error inflating class SwitchCompat
レイアウト用 xml での宣言を SwitchCompat ではなく android.support.v7.widget.SwitchCompat とフルパスで指定したら解消しました。
Android : NumberPicker の Divider の色を変える
こんな感じに、緑色にしてみました。
java.lang.reflect を使って NumberPicker の mSelectionDivider に独自の drawable を設定することで実現します。
Class<?> numberPickerClass = null;
try{
numberPickerClass = Class.forName("android.widget.NumberPicker");
} catch (ClassNotFoundException e) {
Log.e(LOGTAG, e.toString());
}
if(numberPickerClass != null){
java.lang.reflect.Field selectionDivider;
try {
selectionDivider = numberPickerClass.getDeclaredField("mSelectionDivider");
selectionDivider.setAccessible(true);
Drawable drawable = getResources().getDrawable(R.drawable.numberpicker_selection_divider);
selectionDivider.set(number_picker, drawable);
} catch (NoSuchFieldException e) {
Log.e(LOGTAG, e.toString());
} catch (IllegalAccessException e) {
Log.e(LOGTAG, e.toString());
}
}
drawable には元の drawable のように右のような 9.patch を使っています →

広告 : 良いAndroidアプリを作る139の鉄則
2014年10月27日月曜日
__attribute__((naked)) の意味:prologue コードと epilogue コードを生成しない
__attribute__((naked)) void Wait10Cycles(void){
asm (
/* bl to here: [4] */
"nop \n\t" /* [1] */
"nop \n\t" /* [1] */
"nop \n\t" /* [1] */
"bx lr \n\t" /* [3] */
);
}
ある場所で見かけた「何もせず待つ」という関数の中身を調べたところ↑のようになっていたので _attribute__((naked)) の意味について調べたことをメモしておきます。
参考 : Declaring Attributes of Functions
This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. It allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only Basic asm statements can safely be included in naked functions (see Basic Asm). While using Extended asm or a mixture of Basic asm and “C” code may appear to work, they cannot be depended upon to work reliably and are not supported.まとめると
- コンパイラに関数定義を作成させつつ、関数の中身は assembly コードで書ける
- prologue コードと epilogue コードが生成されない
- 関数内で安全に使用できるのは Basic asm のみ。拡張アセンブラ構文(Extended asm)や Cコードも動くように見えるかもしれないがサポートされていない。
Prologue コード(プロローグコード)とは
関数の先頭で、関数内で使用するスタックやレジスタの準備を行うコードのことEpilogue コード(エピローグコード)とは
関数の終わりで、スタックやレジスタを関数が呼ばれる前の状態に戻すコードのことFunction prologue(英語版 Wikipedia へのリンク)
2014年10月26日日曜日
AQM0802A を FRDM-KL25Z + CodeWarrior 環境で使用する
秋月で I2C接続小型LCDモジュールピッチ変換キット (AQM0802A-RN-GBW ピッチ変換基板付き)を購入して、FRDM-KL25Z と接続して表示してみました。
紆余曲折ありつつ、最終的にはなんとか表示できたので、ハマったところのメモを残しておきます。
以下にコードをベタ貼りしておきます。
(※ I2CMasterHelper_***、BusyWait は別の場所で定義した関数なので、このままでは使えませんが、参考程度に。)
紆余曲折ありつつ、最終的にはなんとか表示できたので、ハマったところのメモを残しておきます。
- CodeWarrior (Processor Expert) の設定で入力する I2C スレーブアドレスは 0x7C ではなく 0x3E
- 0x3E は 0x7C >> 1。アドレス部と Read/Write 部を独立して扱っているので、シフトしておく必要があります。
- 初期設定例だと表示されない
- コントラストの設定(初期化手順 4 番目)を例の 0x70 から 0x7f に変更すると見えるようになりました。
- 供給している電源電圧の問題かもしれません。電源入力には FRDM-KL25Z の 5V 出力端子からの電圧を TA48033S で 3.3V にして使用しました。
- 初期化コマンド間で Wait する
- 長い時間が指定されている Wait の時間は 26.3uS ということで、特に気にしないで連続でコマンドを発行しても発行にかかる時間で Wait 時間がまかなえるかと思ったのですが、たまに通信に失敗することがありました。他の原因かもしれませんが、とりあえずコマンドの間に長めの Wait(1ms) を入れることで安定しました。
また、Control Byte の Co が若干わかりにくかったのですが、表示したい文字列を送る場合は 0 にして、それ以外の場合はコマンド1つ毎に STOP コンディションを発生させれ Co は 0 でも 1 でも良い、という扱いで良さそうです。コマンド間で Wait も必要なようですし。
仕様書には「データを複数送る場合 Co = 1 で、」とありますが、これは間違いですね。少なくとも Co = 0 にして文字列を送ることはできました。
(※ I2CMasterHelper_***、BusyWait は別の場所で定義した関数なので、このままでは使えませんが、参考程度に。)
#include "AQM0802A.h"
#include "I2CMasterHelper.h"
#include "PE_Types.h"
#include "PE_Error.h"
#include <stdio.h>
#include <string.h>
// co = 0 : Last Control byte to be sent. Only a stream of data bytes is allowed to follow.
// co = 1 : Another Control byte will follow the data byte (unless a STOP condition is received)
// rs = 0 : Send Command
// rs = 1 : Send Data
static byte ControlByte(bool co, bool rs){
return (co << 7) | (rs << 6);
}
static void SendCommand(byte cmd){
byte data[2];
data[0] = ControlByte(FALSE, FALSE);
data[1] = cmd;
I2CMasterHelper_SendBlock(data, 2, LDD_I2C_SEND_STOP);
I2CMasterHelper_WaitSendComplete();
BusyWaitMS(1);
}
void AQM0802A_Init(){
// 0x0011_1000 : DL = 1 : 8bit-bus mode, N = 1 : 2-line display mode, DH = 0 : font size is 5 x 8, IS = 0 : normal instruction
SendCommand(0x38);
// IS = 1
SendCommand(0x39);
// Internal OSC frequency : 1/4 bias
SendCommand(0x14);
// Contrast Set : 000
SendCommand(0x7f);
// Power/ICON/Contrast control : ICON display off, Booster circuit on, contrast 10
SendCommand(0x56);
// Follower control : follower circuit on, follower amplified ratio = 100
SendCommand(0x6C);
// wait 200ms for power stable
BusyWaitMS(200);
SendCommand(0x38);
// Display on, cursor off, cursor blink off
SendCommand(0x0C);
// Clear display
SendCommand(0x01);
// TODO: wait 1.08ms
BusyWaitMS(2);
}
// first line address is 0x00 ~ 0x07
// second line address is 0x40 ~ 0x47
void AQM0802A_DisplayChr(byte addr, char ch){
// Test for now;
byte data[4];
// Set Address
data[0] = ControlByte(TRUE, FALSE);
data[1] = 0x80 | addr; // the first bit is always 1.
// Set Character
data[2] = ControlByte(FALSE, TRUE);
data[3] = ch;
I2CMasterHelper_SendBlock(data, 4, LDD_I2C_SEND_STOP);
I2CMasterHelper_WaitSendComplete();
}
void AQM0802A_DisplayStr(bool secondline, char* str){
byte data[11];
byte length = strlen(str);
if(length > 8){
length = 8;
}
// Set Address
data[0] = ControlByte(TRUE, FALSE);
data[1] = 0x80 | ((secondline == TRUE)?0x40:0x00); // the first bit is always 1.
// Set data
data[2] = ControlByte(FALSE, TRUE);
memcpy(data + 3, str, length);
I2CMasterHelper_SendBlock(data, length + 3, LDD_I2C_SEND_STOP);
I2CMasterHelper_WaitSendComplete();
}
void AQM0802A_ClearDisplay(){
SendCommand(0x01);
}
登録:
投稿 (Atom)
