2010年3月3日星期三

Change bash shell style

3 special shell paramenters to set the shell looks:

* PS1 - The value of this parameter is expanded (see PROMPTING below) and used as the primary prompt string. The default value is \s-\v\$ .
* PS2 - The value of this parameter is expanded as with PS1 and used as the secondary prompt string. The default is >
* PS3 - The value of this parameter is used as the prompt for the select command
* PS4 - The value of this parameter is expanded as with PS1 and the value is printed before each command bash displays during an execution trace. The first character of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is +

PS1 options:
* \a : an ASCII bell character (07)
* \d : the date in "Weekday Month Date" format (e.g., "Tue May 26")
* \D{format} : the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
* \e : an ASCII escape character (033)
* \h : the hostname up to the first '.'
* \H : the hostname
* \j : the number of jobs currently managed by the shell
* \l : the basename of the shell’s terminal device name
* \n : newline
* \r : carriage return
* \s : the name of the shell, the basename of $0 (the portion following the final slash)
* \t : the current time in 24-hour HH:MM:SS format
* \T : the current time in 12-hour HH:MM:SS format
* \@ : the current time in 12-hour am/pm format
* \A : the current time in 24-hour HH:MM format
* \u : the username of the current user
* \v : the version of bash (e.g., 2.00)
* \V : the release of bash, version + patch level (e.g., 2.00.0)
* \w : the current working directory, with $HOME abbreviated with a tilde
* \W : the basename of the current working directory, with $HOME abbreviated with a tilde
* \! : the history number of this command
* \# : the command number of this command
* \$ : if the effective UID is 0, a #, otherwise a $
* \nnn : the character corresponding to the octal number nnn
* \\ : a backslash
* \[ : begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
* \] : end a sequence of non-printing characters

e.g.
PS1="\s-\u:\W\$ "
output : bash-myDesktop:Pictures$

how to change color

2010年2月3日星期三

ARM Note

****************************
*** CRC
****************************
下面以最常用的CRC-16为例来说明其生成过程。

CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果LSB为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。

CRC的计算过程:
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。

The sample code searched from web:

//-- reverse order of 0x8005 (X16+X15+X2+1, CRC-16, ignored MSB X16)
//-- since we are XORing bit0 of the data
volatile unsigned short CRCPOLY16 = 0xA001;

//-- bit-at-a-time CRC-16 algorithm
unsigned short crc16( unsigned char *data, unsigned char len)
{
unsigned char i;
unsigned char j;
unsigned short byte;
unsigned short crc;
unsigned short mask;

i = 0;
crc = 0xFFFF;

while( i < len )
{
if( data[i] != 0 )
{
byte = data[i]; //-- get next byte
crc = crc ^ byte;
for( j=8; j>0; j-- )
{
mask = -(crc & 1);
crc = (crc >> 1) ^ (CRCPOLY16 & mask);
}
}
i++;
}
return ~crc;
}

********************** END CRC *****************

**************************************************
** I2C Slave mode
**************************************************
Sample code for ARM7 :

"i2c_slave.h" :
#ifndef __I2C_SLAVE_H__
#define __I2C_SLAVE_H__

void IRQ_I2C0_SLV (void) __attribute__ ((interrupt("IRQ")));
volatile unsigned char I2C_SlaveRcv;
volatile unsigned char *I2C_SlaveSndBuf;
volatile unsigned char I2C_Snd_num;
volatile unsigned char I2C_SlvSnd_end;
volatile unsigned char I2C_NoOfByte;
void Initialize_I2C0_SLV( unsigned int irq_slot, unsigned char id, unsigned char noofbyte);
void IRQ_I2C0_SLV(void);
void I2C_Slv_SendData( unsigned char *s);

#endif // __I2C_SLAVE_H__

"i2c_slave.c" :
void Initialize_I2C0_SLV( unsigned int irq_slot, unsigned char id, unsigned char noofbyte)
{
volatile unsigned long *addr;
PINSEL0 |= 0x00000050; //-- p0.2=SDA0, p0.3=SCL0
I2C0ADR = ( id << 1); //-- set I2C slave address, shitf 1-bit left to filter r/w bit
I2C0CONSET = 0x44; //-- enable I2C hardware and set AA (ack) to enable slave mode
addr = &VICVectCntl0;
*(addr + irq_slot) = 0x00000020 | VIC_I2C0;
addr = &VICVectAddr0;
*(addr + irq_slot) = ( unsigned int ) &IRQ_I2C0_SLV;

VICIntSelect &= ~( 1 << VIC_I2C0);
VICIntEnable |= ( 1 << VIC_I2C0);

I2C_NoOfByte = noofbyte;
I2C_SlaveSndBuf = NULL;
I2C_Snd_num = I2C_NoOfByte;
I2C_SlvSnd_end = 1;
}

void IRQ_I2C0_SLV(void)
{
unsigned char sta;

sta = I2C0STAT;
//I2C0CONCLR = 0x2C; //-- clear STA, AA and SI
I2C0CONCLR = 0x24; //-- clear STA and AA

switch( sta)
{
//-- slave receiver mode
case 0x60: //-- own SLA+W has been received, ack has been returned, no I2CDAT action
I2C0CONSET = 0x04; //-- set AA, will receive data and return ACK
break;
case 0x68: //-- address as slave
I2C0CONSET = 0x04; //-- set AA, return ACK on first byte
break;
case 0x70:
break;
case 0x78:
break;
case 0x80: //-- Data received, ACK returned
I2C_SlaveRcv = I2C0DAT; //-- read and store data, NACK on next byte
I2C0CONSET = 0x04;
break;
case 0x88: //-- data received, NACK returned, will exit slave mode
I2C0CONSET = 0x04; //-- set to not addressed slave
break;
case 0xA0: //-- STOP or repeat START received with addressed as slave, will leave slave mode
I2C0CONSET = 0x04; //-- set AA to re-enter slave mode
break;

//-- slave transmitter mode
case 0xA8: //-- own SLA+R received, ACK returned (slave transmitted)
I2C_SlvSnd_end = 0; //-- start send bytes
I2C_Snd_num = I2C_NoOfByte; //-- initiate pointer
I2C0DAT = *I2C_SlaveSndBuf; //-- first byte will be sent;
I2C0CONSET = 0x04; //-- current data byte will be transmitted, ACK will be received, AA=1
break;
case 0xB0: //-- Arbitration lost, enter slave transmitter mode
break;
case 0xB8: //-- Data transmitted, ACK received
I2C_Snd_num--; //-- decrease data byte counter
I2C0DAT = *(I2C_SlaveSndBuf + (I2C_NoOfByte - I2C_Snd_num));
if( I2C_Snd_num > 0 ) //-- if not the last byte
{
I2C0CONSET = 0x04; //-- Data byte will be transmitted, ACK will be received, AA=1
}
else //-- the last byte
{
I2C0CONCLR = 0x04; //-- Last data byte will be sent and ACK will be received, AA=0
}
break;
case 0xC0: //-- Data byte transmitted, NACK received(end of master receive mode), not addressed slave entered
I2C0CONSET = 0x04; //-- set AA, switch to not addressed mode
I2C_Snd_num = I2C_NoOfByte; //-- reset counter
I2C_SlvSnd_end = 1; //-- reset end of send byte flag
break;
case 0xC8: //-- Last data transmitted, ACK received
I2C_Snd_num = I2C_NoOfByte; //-- reset counter
I2C_SlvSnd_end = 1; //-- reset end of byte flag
I2C0CONSET = 0x04; //-- Set AA, switch to not addressed slave mode
break;
default:
I2C_Snd_num = I2C_NoOfByte; //-- reset counter
I2C_SlvSnd_end = 0; //-- reset end of byte flag
break;
}
I2C0CONCLR = 0x08; //-- clear SI
VICVectAddr = 0x00; //-- reset VIC
}

void I2C_Slv_SendData( unsigned char *s)
{
if( I2C_SlvSnd_end == 1)
I2C_SlaveSndBuf = s;
}

******************** END I2C Slave mode ************************