A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 186 lines 4.5 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2002 by Linus Nielsen Feltzing 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include <stdio.h> /* get NULL */ 23#include "config.h" 24 25#include "kernel.h" 26#include "rtc.h" 27#ifdef HAVE_RTC_IRQ 28#include "rtc-target.h" 29#endif 30#include "timefuncs.h" 31#include "debug.h" 32 33static struct tm tm; 34 35time_t dostime_mktime(uint16_t dosdate, uint16_t dostime) 36{ 37 /* this knows our mktime() only uses these struct tm fields */ 38 struct tm tm; 39 tm.tm_sec = ((dostime ) & 0x1f) * 2; 40 tm.tm_min = ((dostime >> 5) & 0x3f); 41 tm.tm_hour = ((dostime >> 11) ); 42 tm.tm_mday = ((dosdate ) & 0x1f); 43 tm.tm_mon = ((dosdate >> 5) & 0x0f) - 1; 44 tm.tm_year = ((dosdate >> 9) ) + 80; 45 46 return mktime(&tm); 47} 48 49void dostime_localtime(time_t time, uint16_t* dosdate, uint16_t* dostime) 50{ 51 struct tm tm; 52#if (CONFIG_PLATFORM & PLATFORM_NATIVE) 53 gmtime_r(&time, &tm); 54#else 55 localtime_r(&time, &tm); 56#endif 57 58 *dostime = ((tm.tm_sec / 2) << 0)| 59 ((tm.tm_min ) << 5)| 60 ((tm.tm_hour ) << 11); 61 *dosdate = ((tm.tm_mday ) << 0)| 62 ((tm.tm_mon + 1) << 5)| 63 ((tm.tm_year - 80) << 9); 64} 65 66#if !CONFIG_RTC 67static inline bool rtc_dirty(void) 68{ 69 return true; 70} 71 72static inline int rtc_read_datetime(struct tm *tm) 73{ 74 tm->tm_sec = 0; 75 tm->tm_min = 0; 76 tm->tm_hour = 0; 77 tm->tm_mday = 1; 78 tm->tm_mon = 0; 79 tm->tm_year = 70; 80 tm->tm_wday = 4; 81 tm->tm_yday = 0; 82 return 1; 83} 84#endif /* !CONFIG_RTC */ 85 86#if CONFIG_RTC 87bool valid_time(const struct tm *tm) 88{ 89 if (!tm || (tm->tm_hour < 0 || tm->tm_hour > 23 || 90 tm->tm_sec < 0 || tm->tm_sec > 59 || 91 tm->tm_min < 0 || tm->tm_min > 59 || 92 tm->tm_year < 100 || tm->tm_year > 199 || 93 tm->tm_mon < 0 || tm->tm_mon > 11 || 94 tm->tm_wday < 0 || tm->tm_wday > 6 || 95 tm->tm_mday < 1 || tm->tm_mday > 31)) 96 return false; 97 else 98 return true; 99} 100 101/* Don't read the RTC more than once per second 102 * returns true if the rtc needs to be read 103 * targets may override with their own implementation 104 */ 105#ifndef HAVE_RTC_IRQ 106static inline bool rtc_dirty(void) 107{ 108 static long timeout = 0; 109 110 /* Don't read the RTC more than once per second */ 111 if (TIME_AFTER(current_tick, timeout)) 112 { 113 /* Once per second, 1/5th of a second off */ 114 timeout = current_tick / HZ * HZ + 6*HZ / 5; 115 return true; 116 } 117 118 return false; 119} 120#endif /* HAVE_RTC_IRQ */ 121#endif /* CONFIG_RTC */ 122 123struct tm *get_time(void) 124{ 125 if (rtc_dirty()) 126 { 127 rtc_read_datetime(&tm); 128 tm.tm_isdst = -1; /* Not implemented for now */ 129 } 130 131 return &tm; 132} 133 134int set_time(const struct tm *tm) 135{ 136#if CONFIG_RTC 137 int rc; 138 139 if (valid_time(tm)) 140 { 141 rc = rtc_write_datetime(tm); 142 143 if (rc < 0) 144 return -1; 145 else 146 return 0; 147 } 148 else 149 { 150 return -2; 151 } 152#else /* No RTC */ 153 (void)tm; 154 return -1; 155#endif /* RTC */ 156} 157 158#if CONFIG_RTC 159void set_day_of_week(struct tm *tm) 160{ 161 int y=tm->tm_year+1900; 162 int d=tm->tm_mday; 163 int m=tm->tm_mon; 164 static const char mo[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; 165 166 if(m == 0 || m == 1) y--; 167 tm->tm_wday = (d + mo[m] + y + y/4 - y/100 + y/400) % 7; 168} 169 170void set_day_of_year(struct tm *tm) 171{ 172 int y=tm->tm_year+1900; 173 int d=tm->tm_mday; 174 int m=tm->tm_mon; 175 d+=m*30; 176 if( ( (m>1) && !(y%4) ) && ( (y%100) || !(y%400) ) ) 177 d++; 178 if(m>6) 179 { 180 d+=4; 181 m-=7; 182 } 183 tm->tm_yday = d + ((m+1) /2); 184} 185#endif /* CONFIG_RTC */ 186