#include #include #include #include #include #define MCP7941X 0x6f #define CTRLREG 0x07 #define ALARM0REG 0x0a #define ALARMREGSETLEN 6 #define ALARMMC 0x70 #define RTCOUT1 0x80 #define ALARM0EN 0x10 #define MINTIMEGAP 120 char int2bcd(char val) { return (val%10+16*(val/10)); } int main(int argc, char *argv[]) { int file; int i2cbus; // I2C bus number char i2cdevicename[11]; char cbuffer[2]; // I2C Control Buffer char buffer[ALARMREGSETLEN+1]; // I2C Alarm0 Buffer char *end; time_t atime; // Alarm time in seconds since epoch time_t now = time(NULL); struct tm *alarm; // Alarm in broken down time /* get command line parameters */ if (argc != 3) { printf("Error: 2 Parameters expected.\n"); exit(1); } i2cbus = strtol(argv[1], &end, 0); if (*end || i2cbus < 0 || i2cbus > 1) { printf("Error: I2C Bus Number 0 or 1 expected.\n"); exit(2); } atime = strtol(argv[2], &end, 0); if (*end || atime < 0) { printf("Error: Alarm time zero or greater expected.\n"); exit(3); } /* set RTC control and ALARM0 accordingly */ if (atime == 0) { // in case alarm time is zero then ... int i; cbuffer[1] = RTCOUT1; // ... simply switch off ... for (i=1; i<=ALARMREGSETLEN; i++) buffer[i]=0; // ... and clear alarm time } else { // in case of a non-zero alarm time .... cbuffer[1] = ALARM0EN; // ... enable the alarm ... if (atime - now < MINTIMEGAP) atime = now + MINTIMEGAP; // ... make alarm causal ... alarm = gmtime(&atime); if (alarm->tm_sec > 59) alarm->tm_sec = 59; // ... skip any leap seconds if any ... buffer[1] = int2bcd(alarm->tm_sec); // and write seconds buffer[2] = int2bcd(alarm->tm_min); // minutes buffer[3] = int2bcd(alarm->tm_hour); // hour buffer[4] = int2bcd(alarm->tm_wday+1); // day of week buffer[4] |= ALARMMC; // add alarm match condition and write buffer[5] = int2bcd(alarm->tm_mday); // day of month buffer[6] = int2bcd(alarm->tm_mon+1); // month } /* open i2c device */ snprintf(i2cdevicename, 11, "/dev/i2c-%d", i2cbus); file = open(i2cdevicename, O_WRONLY); if (file < 0) { printf("Error: Can't open /dev/i2c-%d.\n", i2cbus); exit(4); } if (ioctl(file, I2C_SLAVE_FORCE, MCP7941X) < 0) { printf("Error: Can't attach I2C Client 0x%x.\n", MCP7941X); exit(5); } /* write alarm0 to RTC */ buffer[0] = ALARM0REG; // set ALARM0 register address if (write(file, buffer, ALARMREGSETLEN+1) != ALARMREGSETLEN+1) { printf("Error: Can't write alarm to I2C Client 0x%x.\n", MCP7941X); exit(6); } /* activate alarm and deactivate power rail */ cbuffer[0] = CTRLREG; // set RTC control register address if (write(file, cbuffer, 2) != 2) { printf("Error: Can't write configuration to I2C Client 0x%x.\n", MCP7941X); exit(7); } exit(0); }