2011年8月17日水曜日

Cortex-M0 NUC120-SDKボード味見(4)

NUC120 SDK で HOS-V4a -2011-0405を眺めています。
-----
HOS では Idle 時_kernel_wai_int()が呼ばれるようです。

kernel/source/arch/proc/arm/arm_v6m/gcc/kwai_int.S
_kernel_wai_int: /* WaitForInterrupt */
+ wfi
b _kernel_wai_int
.size _kernel_wai_int, .-_kernel_wai_int
で wfi命令(sleep)を追加してみました。

効果は CPU48MHz SysTick 1ms周期で wfi命令なし130mA, wfi命令あり100mA と消費電力が低減しました。
----
I2C0(PA8.SDC,PA9.SCL)に 温度センサーLM73を接続してみました。
LM73は http://www.digikey.jp/ で購入しました。

sample/arm/nuc120/i2c0_lm73.c
/**
* Sample program for Hyper Operating System V4 Advance
*
* @file sample.c
* @brief %jp{サンプルプログラム}%en{Sample program}
*
* Copyright (C) 1998-2011 by Project HOS
* http://sourceforge.jp/projects/hos/
*/

#include
#include
#include "kernel.h"
#include "kernel_id.h"
#include "uart.h"
#include "nuc120_reg.h"

extern volatile long OSTick;

struct i2c_lm73_t {
unsigned short temperature;
char valid;
unsigned char ad;
unsigned char rd[2];
} lm73;

#define LM73_AD (0x49)

/** %jp{サンプルタスク} */
void Lm73_Task(VP_INT exinf)
{

lm73.ad = (LM73_AD<<1);
lm73.temperature=0;
/* I2C0 pin function */
*REG_GPA_MFP |= (3<<8);/* I2C0 */

/* I2C0 engine clock enable */
*REG_APBCLK |= (1 << 8); /* I2C0 CLK Enable */

/* I2C0 初期化 */
*REG_I2C0_I2CON = 0x08; /* clearing all flags */
*REG_I2C0_I2CON = 0xc0; /* Enable EI + ENS1 */
*REG_I2C0_I2CLK = 119;/* 100KHz */

ena_int(18);

for(;;)
{
lm73.valid=0;

*REG_I2C0_I2CON |= 0x20;/* STA */

dly_tsk (1000);

if(lm73.valid) { /* */
/** %jp{状態表示} */
wai_sem(SEMID_UART);

/* %jp{文字列生成} */
lm73.temperature=lm73.rd[0]<<8|lm73.rd[1];
printk("LM73: %3d.%02d\n",lm73.temperature>>7,100*(lm73.temperature>>5 & 3)/4);

sig_sem(SEMID_UART);
}
}
}


void
I20_ISR_8 ()
{
// printk("<08>");
/* Clear SI and Start flag */
*REG_I2C0_I2CON &= ~0x34; /* */
*REG_I2C0_I2CON |= 0x08; /* SIC */
/* Slave address + write */
*REG_I2C0_I2CDAT = lm73.ad;
}
void
I20_ISR_10 ()
{
// printk("<10>");
/* clear SI */
*REG_I2C0_I2CON |= 0x08;
*REG_I2C0_I2CON &= ~0x34;
/* Slave address + read */
*REG_I2C0_I2CDAT = lm73.ad|1;
}
void
I20_ISR_18 ()
{
// printk("<18>");
/* Data to be transmitted */
*REG_I2C0_I2CDAT = 0x00;/* Reg 0 */
/* clear SI */
*REG_I2C0_I2CON |= 0x0c;
*REG_I2C0_I2CON &= ~0x20;
}

void
I20_ISR_20 ()
{
// printk("<20>");
/* Data to be transmitted */
*REG_I2C0_I2CDAT = 0x00;/* LM73 Reg 0 */
/* clear SI */
*REG_I2C0_I2CON |= 0x08;
*REG_I2C0_I2CON &= ~0x34;
}
void
I20_ISR_28 ()
{
// printk("<28>");
/* Transmit stop condition */
*REG_I2C0_I2CON &= ~0x34;
/* clear SI */
*REG_I2C0_I2CON |= 0x28;
}

void
I20_ISR_30 ()
{
// printk("<30>");
/* clear SI */
*REG_I2C0_I2CON |= 0x18;
}

void
I20_ISR_38 ()
{
// printk("<38>");
/* clear SI */
*REG_I2C0_I2CON |= 0x8;
}

void
I20_ISR_40 ()
{
// printk("<40>");
/* clear SI */
*REG_I2C0_I2CON &= ~0x34;
*REG_I2C0_I2CON |= 0x08;
/* Transmit AA condition */
*REG_I2C0_I2CON |= 0x04;
}
void
I20_ISR_48 ()
{
// printk("<48>");
/* clear SI */
*REG_I2C0_I2CON |= 0x08;
}
void
I20_ISR_50 ()
{
// printk("<50>");
lm73.rd[0]=*REG_I2C0_I2CDAT;
/* clear SI */
*REG_I2C0_I2CON |= 0x08;
/* Transmit AA condition */
*REG_I2C0_I2CON &= ~0x24;
}
void
I20_ISR_58 ()
{
// printk("<58>");
lm73.rd[1]=*REG_I2C0_I2CDAT;
lm73.valid++;
/* clear SI */
*REG_I2C0_I2CON &= ~0x24;
*REG_I2C0_I2CON |= 0x18;
}


void I2C0_Isr(VP_INT exinf)
{
int status;

status = *REG_I2C0_I2CSTATUS & 255;

switch (status)
{
case 0x08:
I20_ISR_8 ();
break;
case 0x10:
I20_ISR_10 ();
break;
case 0x18:
I20_ISR_18 ();
break;
case 0x20:
I20_ISR_20 ();
break;
case 0x28:
I20_ISR_28 ();
break;
case 0x30:
I20_ISR_30 ();
break;
case 0x38:
I20_ISR_38 ();
break;
case 0x40:
I20_ISR_40 ();
break;
case 0x48:
I20_ISR_48 ();
break;
case 0x50:
I20_ISR_50 ();
break;
case 0x58:
I20_ISR_58 ();
break;
default:
*REG_I2C0_I2CON |= 0x08;/* Clear SI */
break;
}
return;
}

/* end of file */
sample/arm/nuc120/nuc120_reg.h
#ifndef _NUC120_DEF_
#define _NUC120_DEF_

#define CLK_BA (0x50000200) /* System Clock Control Register */
#define REG_PWRCON ((volatile UW *)(CLK_BA+0x00)) /* PWRCON Register */
#define REG_AHBCLK ((volatile UW *)(CLK_BA+0x04)) /* AHBCLK Register */
#define REG_APBCLK ((volatile UW *)(CLK_BA+0x08)) /* APBCLK Register */
#define REG_CLKSEL0 ((volatile UW *)(CLK_BA+0x10)) /* CLKSEL0 Register */
#define REG_CLKSEL1 ((volatile UW *)(CLK_BA+0x14)) /* CLKSEL1 Register */
#define REG_CLKDIV ((volatile UW *)(CLK_BA+0x18)) /* CLKDIV Register */
#define REG_CLKSEL2 ((volatile UW *)(CLK_BA+0x1c)) /* CLKSEL2 Register */
#define REG_PLLCON ((volatile UW *)(CLK_BA+0x20)) /* PLLCON Register */

#define GCR_BA (0x50000000) /* System Manager Control Register */
#define REG_SYS_RSTSRC ((volatile UW *)(GCR_BA+0x004)) /* GPIO Register */
#define REG_SYS_IPRSTC1 ((volatile UW *)(GCR_BA+0x008)) /* GPIO Register */
#define REG_SYS_IPRSTC2 ((volatile UW *)(GCR_BA+0x00c)) /* GPIO Register */
#define REG_GPA_MFP ((volatile UW *)(GCR_BA+0x030)) /* GPIO Register */
#define REG_GPB_MFP ((volatile UW *)(GCR_BA+0x034)) /* GPIO Register */
#define REG_GPC_MFP ((volatile UW *)(GCR_BA+0x038)) /* GPIO Register */
#define REG_GPD_MFP ((volatile UW *)(GCR_BA+0x03c)) /* GPIO Register */
#define REG_GPE_MFP ((volatile UW *)(GCR_BA+0x040)) /* GPIO Register */

#define REG_WRPROT ((volatile UW *)(GCR_BA+0x100)) /* REGWRPROT Register */

#define GP_BA (0x50004000) /* System Manager Control Register */
#define REG_GPIOA_PMD ((volatile UW *)(GP_BA+0x000)) /* GPIOB Register */
#define REG_GPIOA_DOUT ((volatile UW *)(GP_BA+0x008)) /* GPIOB Register */
#define REG_GPIOB_PMD ((volatile UW *)(GP_BA+0x040)) /* GPIOB Register */
#define REG_GPIOB_DOUT ((volatile UW *)(GP_BA+0x048)) /* GPIOB Register */
#define REG_GPIOC_PMD ((volatile UW *)(GP_BA+0x080)) /* GPIOB Register */
#define REG_GPIOC_DOUT ((volatile UW *)(GP_BA+0x088)) /* GPIOB Register */

#define ADC_BA (0x400e0000) /* ADC Registers */
#define REG_ADC_ADDR0 ((volatile UW *)(ADC_BA+0x000)) /* ADC0 Register */
#define REG_ADC_ADDR1 ((volatile UW *)(ADC_BA+0x004)) /* ADC1 Register */
#define REG_ADC_ADDR2 ((volatile UW *)(ADC_BA+0x008)) /* ADC2 Register */
#define REG_ADC_ADDR3 ((volatile UW *)(ADC_BA+0x00c)) /* ADC3 Register */
#define REG_ADC_ADDR4 ((volatile UW *)(ADC_BA+0x010)) /* ADC4 Register */
#define REG_ADC_ADDR5 ((volatile UW *)(ADC_BA+0x014)) /* ADC5 Register */
#define REG_ADC_ADDR6 ((volatile UW *)(ADC_BA+0x018)) /* ADC6 Register */
#define REG_ADC_ADDR7 ((volatile UW *)(ADC_BA+0x01c)) /* ADC7 Register */
#define REG_ADC_ADCR ((volatile UW *)(ADC_BA+0x020)) /* ADCR Register */
#define REG_ADC_ADCHER ((volatile UW *)(ADC_BA+0x024)) /* ADCHER Register */
#define REG_ADC_ADSR ((volatile UW *)(ADC_BA+0x030)) /* ADSR Register */

#define TMR_BA01 (0x40010000) /* TMR01 */
#define REG_TMR_TCSR0 ((volatile UW *)(TMR_BA01+0x00)) /* UART Receiver Buffer Register */
#define REG_TMR_TCMPR0 ((volatile UW *)(TMR_BA01+0x04)) /* UART Transmitter Holding Register */
#define REG_TMR_TISR0 ((volatile UW *)(TMR_BA01+0x08)) /* UART Divisor Latch LSB and MSB Registers */
#define REG_TMR_TDR0 ((volatile UW *)(TMR_BA01+0x0c)) /* UART Divisor Latch LSB and MSB Registers */
#define REG_TMR_TCSR1 ((volatile UW *)(TMR_BA01+0x20)) /* UART Receiver Buffer Register */
#define REG_TMR_TCMPR1 ((volatile UW *)(TMR_BA01+0x24)) /* UART Transmitter Holding Register */
#define REG_TMR_TISR1 ((volatile UW *)(TMR_BA01+0x28)) /* UART Divisor Latch LSB and MSB Registers */
#define REG_TMR_TDR1 ((volatile UW *)(TMR_BA01+0x2c)) /* UART Divisor Latch LSB and MSB Registers */

#define I2C0_BA (0x40020000) /* I2C */
#define REG_I2C0_I2CON ((volatile UW *)(I2C0_BA+0x00)) /* I2C ControlRegister */
#define REG_I2C0_I2CADDR0 ((volatile UW *)(I2C0_BA+0x04)) /* I2C Slave Address Register0 */
#define REG_I2C0_I2CDAT ((volatile UW *)(I2C0_BA+0x08)) /* I2C DATA Registers */
#define REG_I2C0_I2CSTATUS ((volatile UW *)(I2C0_BA+0x0c)) /* I2C Status Registers */
#define REG_I2C0_I2CLK ((volatile UW *)(I2C0_BA+0x10)) /* I2C Clock Registers */
#define REG_I2C0_I2CTOC ((volatile UW *)(I2C0_BA+0x14)) /* I2C Time Out Control Registers */
#define REG_I2C0_I2CADDR1 ((volatile UW *)(I2C0_BA+0x18)) /* I2C Slave Address Register1 */
#define REG_I2C0_I2CADDR2 ((volatile UW *)(I2C0_BA+0x1c)) /* I2C DATA Slave Address Register2 */
#define REG_I2C0_I2CADDR3 ((volatile UW *)(I2C0_BA+0x20)) /* I2C DATA Slave Address Register3 */

#define UART0_BA (0x40050000) /* UART0 */
#define REG_U0RBR ((volatile UW *)(UART0_BA+0x00)) /* UART Receiver Buffer Register */
#define REG_U0THR ((volatile UW *)(UART0_BA+0x00)) /* UART Transmitter Holding Register */
#define REG_U0BAUD ((volatile UW *)(UART0_BA+0x24)) /* UART Divisor Latch LSB and MSB Registers */
#define REG_U0IER ((volatile UW *)(UART0_BA+0x04)) /* UART Interrupt Enable Register */
#define REG_U0ISR ((volatile UW *)(UART0_BA+0x1c)) /* UART Interrupt Identification Register */
#define REG_U0FCR ((volatile UW *)(UART0_BA+0x08)) /* UART FIFO Control Register */
#define REG_U0LCR ((volatile UW *)(UART0_BA+0x0c)) /* UART Line Control Register */
#define REG_U0MCR ((volatile UW *)(UART0_BA+0x10)) /* UART0 Modem Control Register */
#define REG_U0FSR ((volatile UW *)(UART0_BA+0x18)) /* UART FSR Register */
#define REG_U0ALTCON ((volatile UW *)(UART0_BA+0x2c)) /* UART */
#define REG_U0FUNSEL ((volatile UW *)(UART0_BA+0x30)) /* UART */

#endif
/* end of file */

sample/arm/nuc120/system.cfg
/**
* Sample program for Hyper Operating System V4 Advance
*
* @file system.cfg
* @brief %jp{サンプルのコンフィギュレーション}
*
* Copyright (C) 1998-2006 by Project HOS
* http://sourceforge.jp/projects/hos/
*/


/* %jp{カーネル独自の設定}%en{kernel} */
KERNEL_HEP_MEM(256, NULL);
KERNEL_SYS_STK(256, NULL);
KERNEL_INT_STK(512, NULL);
KERNEL_RSV_TSKID(0);
KERNEL_RSV_SEMID(0);
KERNEL_RSV_FLGID(0);
KERNEL_RSV_DTQID(0);
KERNEL_RSV_MBXID(0);
KERNEL_RSV_MPFID(0);
KERNEL_RSV_MTXID(0);
KERNEL_RSV_CYCID(0);


/* %jp{OSタイマの設定}%en{OS timer} */
INCLUDE("\"ostimer.h\"");
ATT_INI({TA_HLNG, 0, OsTimer_Initialize});
DEF_INH(15, {TA_HLNG, OsTimer_Isr}); /* 15:SysTick */
DEF_INH(24, {TA_HLNG, TMR0_Isr}); /* 24:TMR0 */
ATT_INI({TA_HLNG, 0, UART0_Initialize});
DEF_INH(28, {TA_HLNG, UART0_Isr}); /* 28:UART0 */
DEF_INH(34, {TA_HLNG, I2C0_Isr}); /* 34:I2C0 */
DEF_INH(45, {TA_HLNG, ADC_Isr}); /* 45:ADC */

/* %jp{サンプル}%en{Sample program} */
INCLUDE("\"sample.h\"");
ATT_INI({TA_HLNG, 0, Sample_Initialize});

CRE_TSK(TSKID_SAMPLE1, {TA_HLNG | TA_ACT, 1, Sample_Task, 2, 512, NULL});
CRE_TSK(TSKID_SAMPLE2, {TA_HLNG | TA_ACT, 2, Sample_Task, 2, 512, NULL});
CRE_TSK(TSKID_SAMPLE3, {TA_HLNG | TA_ACT, 3, Sample_Task, 2, 512, NULL});
CRE_TSK(TSKID_SAMPLE4, {TA_HLNG | TA_ACT, 4, Sample_Task, 2, 512, NULL});
CRE_TSK(TSKID_SAMPLE5, {TA_HLNG | TA_ACT, 5, Sample_Task, 2, 512, NULL});
CRE_TSK(TSKID_ADC, {TA_HLNG | TA_ACT, 5, Adc_Task, 3, 512, NULL});
CRE_TSK(TSKID_LM73, {TA_HLNG | TA_ACT, 5, Lm73_Task, 3, 512, NULL});
CRE_TSK(TSKID_LED, {TA_HLNG | TA_ACT, 0, Led_PC2, 7, 512, NULL});

CRE_CYC(CYCID_LED, {TA_HLNG , 0, Led_PC3, 250, 0});

CRE_SEM(1, {TA_TFIFO, 1, 1});
CRE_SEM(2, {TA_TFIFO, 1, 1});
CRE_SEM(3, {TA_TFIFO, 1, 1});
CRE_SEM(4, {TA_TFIFO, 1, 1});
CRE_SEM(5, {TA_TFIFO, 1, 1});
CRE_SEM(SEMID_RAND, {TA_TFIFO, 1, 1});
CRE_SEM(SEMID_UART, {TA_TFIFO, 1, 1});
CRE_FLG(FLGID_UART, {TA_TFIFO | TA_WSGL, 0});

/* end of file */



0 件のコメント:

コメントを投稿