最終更新日 平成26年5月15日
起動した後、n キーを押すとNTPで時計を合わせます。
// RXduino sample programs.
// (C)2012-2014 Copyright TokushuDenshiKairo Inc.
#include <rxduino.h>
#include <Ethernet.h>
#include <rtc.h>
#include <time.h>
TEthernet Ethernet;
BOOL onReceiveUDP(unsigned char dest_ip[4], unsigned char src_ip[4],
unsigned short dest_port,unsigned short src_port, unsigned char *data, short datalen);
bool ether_init = false;
#if RTC_LIBRARY_VERSION >= 0x01060000
#define _MYRTC RXRTC
#else
#define _MYRTC RTC
#endif
void ShowRegs(const char *mes)
{
printf("%s\n",mes);
printf("SOSCWTCR=%02X\n",*(volatile unsigned char *)0x000800A3);
printf("SOSCCR=%02X\n",*(volatile unsigned char *)0x00080033);
printf("RCR1=%02X\n",*(volatile unsigned char *)0x0008c422);
printf("RCR2=%02X\n",*(volatile unsigned char *)0x0008c424);
printf("RCR3=%02X\n",*(volatile unsigned char *)0x0008c426);
printf("RCR4=%02X\n",*(volatile unsigned char *)0x0008c428);
}
bool EtherInit()
{
byte mac[] = {2,0,0,0,0,1};
Ethernet.begin(mac);
Ethernet.registUdpHandler(onReceiveUDP);
printf("My ip addr = %s\n",Ethernet.localIP());
ether_init = true;
return Ethernet.isLinkup();
}
void ShowHelp()
{
printf("USAGE:\n");
printf(" a: Adjust RTC to someday\n");
printf(" s: Show registers\n");
printf(" l: Enter osc into low power mode (but it may not able to continue operating)\n");
printf(" r: Reboot this application again\n");
printf(" f: Reboot gr-firmware \n");
printf(" d: Renrew ipaddress by DHCP.\n");
printf(" n: Sync to NTP server (ntp.nict.jp) \n");
printf(" h ?: Show this help \n");
printf("\n");
}
void setup()
{
pinMode(PIN_LED0, OUTPUT);
pinMode(PIN_LED1, OUTPUT);
pinMode(PIN_LED2, OUTPUT);
pinMode(PIN_LED3, OUTPUT);
pinMode(PIN_SW , INPUT);
digitalWrite(PIN_LED0, 1);
Serial.begin(38400, SCI_AUTO);
Serial.setDefault();
digitalWrite(PIN_LED1, 1);
printf("------------------------------\n");
printf("RX RTC test program 2\n");
printf("------------------------------\n");
printf("This program diagnoses and initializes RTC.\n");
ShowHelp();
// ShowRegs("Default registers");
int ret = _MYRTC::begin();
/*
if(ret < 2)
{
_MYRTC::setDateTime( 2013, 1, 2, 2, 14, 00 );
}
*/
// printf("rtc init result=%d\n",ret);
// ShowRegs("After initialization");
}
unsigned long lasttime = 0;
void loop()
{
if(Serial.available())
{
char c = Serial.read();
if(c == 'a') // adjust
{
_MYRTC::setDateTime( 2013, 2, 22, 8, 17, 20 );
}
if(c == 's') // show registers
{
ShowRegs("Current registers");
}
if(c == 'l') // low power mode
{
*(volatile unsigned char *)0x0008c426 = 0x03; // RTCDV=001
ShowRegs("Low power mode");
}
if(c == 'r') // reboot and launch this application again
{
printf("Reboot userapp\n");delay(100);
system_reboot(REBOOT_USERAPP);
}
if(c == 'f') // reboot and launch gr firmware
{
printf("Reboot firmware\n");delay(100);
system_reboot(REBOOT_FIRMWARE);
}
if((c == '?') || (c == 'h'))
{
ShowHelp();
}
if(c == 'd')
{
if(!ether_init) EtherInit();
if(Ethernet.isLinkup())
{
printf("Renew IP address with DHCP...");
if(Ethernet.dhcp())
{
printf("Success! My ip addr = %s\n",Ethernet.localIP());
}
else
{
printf("failed\n");
}
}
}
if(c == 'n')
{
if(!ether_init) EtherInit();
if(Ethernet.isLinkup())
{
printf("NTP test : ntp.nict.jp is ");
byte *ip = Ethernet.gethostbyname("ntp.nict.jp");
printf("Server address: %d.%d.%d.%d\n",ip[0],ip[1],ip[2],ip[3]);
unsigned char buf[12*4];
memset(buf,0,12*4);
buf[0] = 0xe3; // 閏秒:警告 バージョン4 クライアント
buf[1] = 0x00; // 階層不明
buf[2] = 0x04; // 8秒間隔
buf[3] = 0xfa;
buf[5] = 0x01;
buf[9] = 0x01;
Ethernet.sendUDP(ip,123,buf,12*4);
}
else
{
printf("Ether is not connected\n");
}
}
}
if(millis() - lasttime >= 1000)
{
int year,mon,day,hour,min,sec;
_MYRTC::getDateTime( year, mon, day, hour, min, sec );
printf("%04d/%02d/%02d %02d:%02d:%02d\n",year, mon, day, hour, min, sec);
lasttime = millis();
}
}
BOOL onReceiveUDP(
unsigned char dest_ip[4],
unsigned char src_ip[4],
unsigned short dest_port,
unsigned short src_port,
unsigned char *data, // UDPパケットのデータ部
short datalen // UDPパケットのデータの長さ(ヘッダは含まない)
)
{
if(dest_port == 123) // NTP受信!
{
unsigned char LeapIndicator = data[0] >> 6;
unsigned char VersionNumber = (data[0] >> 3) & 0x07;
unsigned char Mode = (data[0] >> 0) & 0x07;
unsigned char Stratum = data[1];
signed char Precision = data[3];
char ReferenceID[5];
memcpy(ReferenceID,&data[12],4);
ReferenceID[4] = '\0';
unsigned long TransTimeH = (data[40] << 24) | (data[41] << 16) | (data[42] << 8) | data[43];
printf("NTPv%d length=%d Mode:",VersionNumber,datalen);
switch(Mode)
{
case 0: printf("Reserved, "); break;
case 1: printf("Synmetic Active, "); break;
case 2: printf("Synmetic Client, "); break;
case 3: printf("Client, "); break;
case 4: printf("Server, "); break;
case 5: printf("Broadcast, "); break;
case 6: printf("Reserved for NTP control, "); break;
case 7: printf("Reserved for private, "); break;
default:printf("Undefined, "); break;
}
printf("Leap indicator:(%d)\n",LeapIndicator);
printf("Stratum %d\n",Stratum);
printf("precisiton %d\n",Precision);
printf("Reference-ID: %s\n",ReferenceID);
// NTP時刻をUNIX時刻に変換
time_t t = TransTimeH - 2208988800UL;
t += 9*60*60; // 日本標準時に変換
struct tm *t_st = localtime(&t);
printf("Transit Timestamp %s\n",asctime(t_st));
printf("Set RTC datetime with NTP result.\n");
int year,mon,day,hour,min,sec;
year = t_st->tm_year;
mon = t_st->tm_mon + 1;
day = t_st->tm_mday;
hour = t_st->tm_hour;
min = t_st->tm_min;
sec = t_st->tm_sec;
_MYRTC::setDateTime(year,mon,day,hour,min,sec);
return TRUE;
}
return false; // この関数で処理したことにしない
}
最初はめちゃくちゃな時間を指していますが、NTPで通信した後は正しい時間になっています。

(C)2012-2014 特殊電子回路株式会社 All Rights Reserved