diff --git a/README.md b/README.md index 5ada111..0596ffe 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ The version in the repository is an ongoing development. It could and will conta Advanced Tuner software for NXP TEF668x tuners with ESP32 board More information: https://www.pe5pvb.nl/tef6686/ +## Time + +You can receive CT time over the RDS on FM, DP666 receivers have a RX8010SJ (driver written by [Wh1teRabbitHU](https://github.com/Wh1teRabbitHU)) and thus can save time between boots, making the radio a high accuracy clock. Enabling the RDS Filter option can delay the clock by a few seconds, however without the filter the clock (from RDS CT) is in perfect sync with my Windows computer synced by NTP + ## Wiki - [About the software & features](https://github.com/PE5PVB/TEF6686_ESP32/wiki) - [Getting started](https://github.com/PE5PVB/TEF6686_ESP32/wiki#getting-started) diff --git a/include/NTPupdate.h b/include/NTPupdate.h index 557c19b..6f0582e 100644 --- a/include/NTPupdate.h +++ b/include/NTPupdate.h @@ -1,5 +1,4 @@ #pragma once -#include #include "globals.h" #include "rtc.hpp" diff --git a/include/Tuner_Drv_Lithio.h b/include/Tuner_Drv_Lithio.h index 6bb1240..3c055db 100644 --- a/include/Tuner_Drv_Lithio.h +++ b/include/Tuner_Drv_Lithio.h @@ -79,8 +79,7 @@ bool devTEF_Get_Cmd(TEF_MODULE module, uint8_t cmd, uint8_t *receive, uint16_t l void devTEF_Radio_Set_Wavegen(bool mode, int16_t amplitude, uint16_t freq); void devTEF_Radio_Get_Quality_Status(uint16_t *status, int16_t *level, uint16_t *usn, uint16_t *wam, int16_t *offset, uint16_t *bandwidth, uint16_t *mod, int8_t *snr); -bool devTEF_Radio_Get_Processing_Status(uint16_t *highcut, uint16_t *stereo, uint16_t *sthiblend, uint8_t *stband_1, uint8_t *stband_2, uint8_t *stband_3, uint8_t *stband_4); uint8_t devTEF_APPL_Get_Operation_Status(); bool devTEF_Radio_Get_Stereo_Status(uint16_t *status); void devTEF_Radio_Get_RDS_Status(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error); -bool devTEF_Radio_Get_RDS_Data(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error); \ No newline at end of file +void devTEF_Radio_Get_RDS_Data(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error); \ No newline at end of file diff --git a/include/constants.h b/include/constants.h index d8836c3..562f2f4 100644 --- a/include/constants.h +++ b/include/constants.h @@ -2,7 +2,7 @@ #include -#define VERSION "v2.20.5d" +#define VERSION "v2.20.5e" #define ROTARY_PIN_A 34 #define ROTARY_PIN_B 36 @@ -48,10 +48,7 @@ #define BATTERY_LOW_VALUE 3.2 #define BATTERY_FULL_VALUE 4.12 -#define XTAL_0V_ADC 0 -#define XTAL_1V_ADC 1050 -#define XTAL_2V_ADC 2250 -#define XTAL_ADC_TOL 300 +#define XTAL_MV_TOL 300 #define LANGUAGE_CHS 14 diff --git a/include/rtc.hpp b/include/rtc.hpp index b9ab276..9c92c11 100644 --- a/include/rtc.hpp +++ b/include/rtc.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include "constants.h" #include #include @@ -11,8 +12,5 @@ extern ESP32Time rtc; extern bool rx_rtc_avail; extern RX8010SJ::Adapter rx_rtc; -void timeToDateTime(time_t t, struct RX8010SJ::DateTime* dateTime); -time_t dateTimeToTime(const struct RX8010SJ::DateTime* dateTime); - -void sync_to_rx_rtc(int32_t offset = 0); -void sync_from_rx_rtc(int32_t offset = 0); \ No newline at end of file +void sync_from_rx_rtc(int32_t offset = 0); +void set_time(time_t time); \ No newline at end of file diff --git a/lib/TFT_eSPI/TFT_eSPI.cpp b/lib/TFT_eSPI/TFT_eSPI.cpp index d638942..78a658b 100644 --- a/lib/TFT_eSPI/TFT_eSPI.cpp +++ b/lib/TFT_eSPI/TFT_eSPI.cpp @@ -1411,31 +1411,16 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da end_tft_write(); } -/*************************************************************************************** -** Function name: setSwapBytes -** Description: Used by 16-bit pushImage() to swap byte order in colours -***************************************************************************************/ void TFT_eSPI::setSwapBytes(bool swap) { _swapBytes = swap; } - -/*************************************************************************************** -** Function name: getSwapBytes -** Description: Return the swap byte order for colours -***************************************************************************************/ bool TFT_eSPI::getSwapBytes(void) { return _swapBytes; } - -/*************************************************************************************** -** Function name: read rectangle (for SPI Interface II i.e. IM [3:0] = "1101") -** Description: Read RGB pixel colours from a defined area -***************************************************************************************/ -// If w and h are 1, then 1 pixel is read, *data array size must be 3 bytes per pixel void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data) { begin_tft_read(); @@ -1893,11 +1878,6 @@ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w end_tft_write(); // Does nothing if Sprite class uses this function } - -/*************************************************************************************** -** Function name: drawBitmap -** Description: Draw an image stored in an array on the TFT -***************************************************************************************/ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor) { //begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write() @@ -1917,10 +1897,6 @@ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w end_tft_write(); // Does nothing if Sprite class uses this function } -/*************************************************************************************** -** Function name: drawXBitmap -** Description: Draw an image stored in an XBM array onto the TFT -***************************************************************************************/ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { //begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write() @@ -1941,10 +1917,6 @@ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t } -/*************************************************************************************** -** Function name: drawXBitmap -** Description: Draw an XBM image with foreground and background colors -***************************************************************************************/ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bgcolor) { //begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write() @@ -1964,22 +1936,12 @@ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t end_tft_write(); // Does nothing if Sprite class uses this function } - -/*************************************************************************************** -** Function name: setCursor -** Description: Set the text cursor x,y position -***************************************************************************************/ void TFT_eSPI::setCursor(int16_t x, int16_t y) { cursor_x = x; cursor_y = y; } - -/*************************************************************************************** -** Function name: setCursor -** Description: Set the text cursor x,y position and font -***************************************************************************************/ void TFT_eSPI::setCursor(int16_t x, int16_t y, uint8_t font) { setTextFont(font); @@ -1987,21 +1949,12 @@ void TFT_eSPI::setCursor(int16_t x, int16_t y, uint8_t font) cursor_y = y; } -/*************************************************************************************** -** Function name: setTextSize -** Description: Set the text size multiplier -***************************************************************************************/ void TFT_eSPI::setTextSize(uint8_t s) { if (s>7) s = 7; // Limit the maximum size multiplier so byte variables can be used for rendering textsize = (s > 0) ? s : 1; // Don't allow font size 0 } - -/*************************************************************************************** -** Function name: setTextColor -** Description: Set the font foreground colour (background is transparent) -***************************************************************************************/ void TFT_eSPI::setTextColor(uint16_t c) { // For 'transparent' background, we'll set the bg @@ -2009,14 +1962,6 @@ void TFT_eSPI::setTextColor(uint16_t c) textcolor = textbgcolor = c; } - -/*************************************************************************************** -** Function name: setTextColor -** Description: Set the font foreground and background colour -***************************************************************************************/ -// Smooth fonts use the background colour for anti-aliasing and by default the -// background is not filled. If bgfill = true, then a smooth font background fill will -// be used. void TFT_eSPI::setTextColor(uint16_t c, uint16_t b, bool bgfill) { textcolor = c; @@ -2024,21 +1969,12 @@ void TFT_eSPI::setTextColor(uint16_t c, uint16_t b, bool bgfill) _fillbg = bgfill; } - -/*************************************************************************************** -** Function name: setPivot -** Description: Set the pivot point on the TFT -*************************************************************************************x*/ void TFT_eSPI::setPivot(int16_t x, int16_t y) { _xPivot = x; _yPivot = y; } -/*************************************************************************************** -** Function name: setBitmapColor -** Description: Set the foreground foreground and background colour -***************************************************************************************/ void TFT_eSPI::setBitmapColor(uint16_t c, uint16_t b) { if (c == b) b = ~c; @@ -2046,32 +1982,17 @@ void TFT_eSPI::setBitmapColor(uint16_t c, uint16_t b) bitmap_bg = b; } - -/*************************************************************************************** -** Function name: setTextWrap -** Description: Define if text should wrap at end of line -***************************************************************************************/ void TFT_eSPI::setTextWrap(bool wrapX, bool wrapY) { textwrapX = wrapX; textwrapY = wrapY; } - -/*************************************************************************************** -** Function name: setTextDatum -** Description: Set the text position reference datum -***************************************************************************************/ void TFT_eSPI::setTextDatum(uint8_t d) { textdatum = d; } - -/*************************************************************************************** -** Function name: setTextPadding -** Description: Define padding width (aids erasing old text and numbers) -***************************************************************************************/ void TFT_eSPI::setTextPadding(uint16_t x_width) { padX = x_width; diff --git a/lib/Time/DateStrings.cpp b/lib/Time/DateStrings.cpp deleted file mode 100644 index 2424678..0000000 --- a/lib/Time/DateStrings.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* DateStrings.cpp - * Definitions for date strings for use with the Time library - * - * Updated for Arduino 1.5.7 18 July 2014 - * - * No memory is consumed in the sketch if your code does not call any of the string methods - * You can change the text of the strings, make sure the short strings are each exactly 3 characters - * the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in TimeLib.h - * - */ - -#include - -// Arduino.h should properly define PROGMEM, PGM_P, strcpy_P, pgm_read_byte, pgm_read_ptr -// But not all platforms define these as they should. If you find a platform needing these -// defined, or if any this becomes unnecessary as platforms improve, please send a pull req. -#if defined(ESP8266) -#undef PROGMEM -#define PROGMEM -#endif - -#include "TimeLib.h" - - -// the short strings for each day or month must be exactly dt_SHORT_STR_LEN -#define dt_SHORT_STR_LEN 3 // the length of short strings - -static char buffer[dt_MAX_STRING_LEN+1]; // must be big enough for longest string and the terminating null - -const char monthStr0[] PROGMEM = ""; -const char monthStr1[] PROGMEM = "January"; -const char monthStr2[] PROGMEM = "February"; -const char monthStr3[] PROGMEM = "March"; -const char monthStr4[] PROGMEM = "April"; -const char monthStr5[] PROGMEM = "May"; -const char monthStr6[] PROGMEM = "June"; -const char monthStr7[] PROGMEM = "July"; -const char monthStr8[] PROGMEM = "August"; -const char monthStr9[] PROGMEM = "September"; -const char monthStr10[] PROGMEM = "October"; -const char monthStr11[] PROGMEM = "November"; -const char monthStr12[] PROGMEM = "December"; - -const PROGMEM char * const PROGMEM monthNames_P[] = -{ - monthStr0,monthStr1,monthStr2,monthStr3,monthStr4,monthStr5,monthStr6, - monthStr7,monthStr8,monthStr9,monthStr10,monthStr11,monthStr12 -}; - -const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec"; - -const char dayStr0[] PROGMEM = "Err"; -const char dayStr1[] PROGMEM = "Sunday"; -const char dayStr2[] PROGMEM = "Monday"; -const char dayStr3[] PROGMEM = "Tuesday"; -const char dayStr4[] PROGMEM = "Wednesday"; -const char dayStr5[] PROGMEM = "Thursday"; -const char dayStr6[] PROGMEM = "Friday"; -const char dayStr7[] PROGMEM = "Saturday"; - -const PROGMEM char * const PROGMEM dayNames_P[] = -{ - dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7 -}; - -const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThuFriSat"; - -/* functions to return date strings */ - -char* monthStr(uint8_t month) -{ - strcpy_P(buffer, (PGM_P)pgm_read_ptr(&(monthNames_P[month]))); - return buffer; -} - -char* monthShortStr(uint8_t month) -{ - for (int i=0; i < dt_SHORT_STR_LEN; i++) - buffer[i] = pgm_read_byte(&(monthShortNames_P[i+ (month*dt_SHORT_STR_LEN)])); - buffer[dt_SHORT_STR_LEN] = 0; - return buffer; -} - -char* dayStr(uint8_t day) -{ - strcpy_P(buffer, (PGM_P)pgm_read_ptr(&(dayNames_P[day]))); - return buffer; -} - -char* dayShortStr(uint8_t day) -{ - uint8_t index = day*dt_SHORT_STR_LEN; - for (int i=0; i < dt_SHORT_STR_LEN; i++) - buffer[i] = pgm_read_byte(&(dayShortNames_P[index + i])); - buffer[dt_SHORT_STR_LEN] = 0; - return buffer; -} diff --git a/lib/Time/Readme.md b/lib/Time/Readme.md deleted file mode 100644 index ba47aeb..0000000 --- a/lib/Time/Readme.md +++ /dev/null @@ -1,165 +0,0 @@ -# Arduino Time Library - -Time is a library that provides timekeeping functionality for Arduino. - -Using the Arduino Library Manager, install "*Time* by *Michael Margolis*". - -The code is derived from the Playground DateTime library but is updated -to provide an API that is more flexible and easier to use. - -A primary goal was to enable date and time functionality that can be used with -a variety of external time sources with minimum differences required in sketch logic. - -Example sketches illustrate how similar sketch code can be used with: a Real Time Clock, -internet NTP time service, GPS time data, and Serial time messages from a computer -for time synchronization. - -## Functionality - -To use the Time library in an Arduino sketch, include TimeLib.h. - -```c -#include -``` - -The functions available in the library include - -```c -hour(); // the hour now (0-23) -minute(); // the minute now (0-59) -second(); // the second now (0-59) -day(); // the day now (1-31) -weekday(); // day of the week (1-7), Sunday is day 1 -month(); // the month now (1-12) -year(); // the full four digit year: (2009, 2010 etc) -``` - -there are also functions to return the hour in 12-hour format - -```c -hourFormat12(); // the hour now in 12 hour format -isAM(); // returns true if time now is AM -isPM(); // returns true if time now is PM - -now(); // returns the current time as seconds since Jan 1 1970 -``` - -The time and date functions can take an optional parameter for the time. This prevents -errors if the time rolls over between elements. For example, if a new minute begins -between getting the minute and second, the values will be inconsistent. Using the -following functions eliminates this problem - -```c -time_t t = now(); // store the current time in time variable t -hour(t); // returns the hour for the given time t -minute(t); // returns the minute for the given time t -second(t); // returns the second for the given time t -day(t); // the day for the given time t -weekday(t); // day of the week for the given time t -month(t); // the month for the given time t -year(t); // the year for the given time t -``` - -Functions for managing the timer services are: - -```c -setTime(t); // set the system time to the give time t -setTime(hr,min,sec,day,mnth,yr); // alternative to above, yr is 2 or 4 digit yr - // (2010 or 10 sets year to 2010) -adjustTime(adjustment); // adjust system time by adding the adjustment value -timeStatus(); // indicates if time has been set and recently synchronized - // returns one of the following enumerations: -timeNotSet // the time has never been set, the clock started on Jan 1, 1970 -timeNeedsSync // the time had been set but a sync attempt did not succeed -timeSet // the time is set and is synced -``` - -Time and Date values are not valid if the status is `timeNotSet`. Otherwise, values can be used but -the returned time may have drifted if the status is `timeNeedsSync`. - -```c -setSyncProvider(getTimeFunction); // set the external time provider -setSyncInterval(interval); // set the number of seconds between re-sync -``` - -There are many convenience macros in the `time.h` file for time constants and conversion -of time units. - -To use the library, copy the download to the Library directory. - -## Examples - -The Time directory contains the Time library and some example sketches -illustrating how the library can be used with various time sources: - -- `TimeSerial.pde` shows Arduino as a clock without external hardware. - It is synchronized by time messages sent over the serial port. - A companion Processing sketch will automatically provide these messages - if it is running and connected to the Arduino serial port. - -- `TimeSerialDateStrings.pde` adds day and month name strings to the sketch above. - Short (3 characters) and long strings are available to print the days of - the week and names of the months. - -- `TimeRTC` uses a DS1307 real-time clock to provide time synchronization. - The basic [DS1307RTC library][1] must be downloaded and installed, - in order to run this sketch. - -- `TimeRTCSet` is similar to the above and adds the ability to set the Real Time Clock. - -- `TimeRTCLog` demonstrates how to calculate the difference between times. - It is a very simple logger application that monitors events on digital pins - and prints (to the serial port) the time of an event and the time period since - the previous event. - -- `TimeNTP` uses the Arduino Ethernet shield to access time using the internet NTP time service. - The NTP protocol uses UDP and the UdpBytewise library is required, see: - - -- `TimeGPS` gets time from a GPS. - This requires the TinyGPS library from Mikal Hart: - - -## Differences - -Differences between this code and the playground DateTime library -although the Time library is based on the DateTime codebase, the API has changed. -Changes in the Time library API: - -- time elements are functions returning `int` (they are variables in DateTime) -- Years start from 1970 -- days of the week and months start from 1 (they start from 0 in DateTime) -- DateStrings do not require a separate library -- time elements can be accessed non-atomically (in DateTime they are always atomic) -- function added to automatically sync time with external source -- `localTime` and `maketime` parameters changed, `localTime` renamed to `breakTime` - -## Technical Notes - -Internal system time is based on the standard Unix `time_t`. -The value is the number of seconds since Jan 1, 1970. -System time begins at zero when the sketch starts. - -The internal time can be automatically synchronized at regular intervals to an external time source. -This is enabled by calling the `setSyncProvider(provider)` function - the provider argument is -the address of a function that returns the current time as a `time_t`. -See the sketches in the examples directory for usage. - -The default interval for re-syncing the time is 5 minutes but can be changed by calling the -`setSyncInterval(interval)` method to set the number of seconds between re-sync attempts. - -The Time library defines a structure for holding time elements that is a compact version of the C `tm` structure. -All the members of the Arduino `tm` structure are bytes and the year is offset from 1970. -Convenience macros provide conversion to and from the Arduino format. - -Low-level functions to convert between system time and individual time elements are provided: - -```c -breakTime(time, &tm); // break time_t into elements stored in tm struct -makeTime(&tm); // return time_t from elements stored in tm struct -``` - -This [DS1307RTC library][1] provides an example of how a time provider -can use the low-level functions to interface with the Time library. - -[1]: diff --git a/lib/Time/Time.cpp b/lib/Time/Time.cpp deleted file mode 100644 index 0dcb29f..0000000 --- a/lib/Time/Time.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - time.c - low level time and date functions - Copyright (c) Michael Margolis 2009-2014 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - 1.0 6 Jan 2010 - initial release - 1.1 12 Feb 2010 - fixed leap year calculation error - 1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this) - 1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update - status, updated examples for Arduino 1.0, fixed ARM - compatibility issues, added TimeArduinoDue and TimeTeensy3 - examples, add error checking and messages to RTC examples, - add examples to DS1307RTC library. - 1.4 5 Sep 2014 - compatibility with Arduino 1.5.7 -*/ - -#if ARDUINO >= 100 -#include -#else -#include -#endif - -#include "TimeLib.h" - -static tmElements_t tm; // a cache of time elements -static time_t cacheTime; // the time the cache was updated -static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds - -void refreshCache(time_t t) { - if (t != cacheTime) { - breakTime(t, tm); - cacheTime = t; - } -} - -int hour() { // the hour now - return hour(now()); -} - -int hour(time_t t) { // the hour for the given time - refreshCache(t); - return tm.Hour; -} - -int hourFormat12() { // the hour now in 12 hour format - return hourFormat12(now()); -} - -int hourFormat12(time_t t) { // the hour for the given time in 12 hour format - refreshCache(t); - if( tm.Hour == 0 ) - return 12; // 12 midnight - else if( tm.Hour > 12) - return tm.Hour - 12 ; - else - return tm.Hour ; -} - -uint8_t isAM() { // returns true if time now is AM - return !isPM(now()); -} - -uint8_t isAM(time_t t) { // returns true if given time is AM - return !isPM(t); -} - -uint8_t isPM() { // returns true if PM - return isPM(now()); -} - -uint8_t isPM(time_t t) { // returns true if PM - return (hour(t) >= 12); -} - -int minute() { - return minute(now()); -} - -int minute(time_t t) { // the minute for the given time - refreshCache(t); - return tm.Minute; -} - -int second() { - return second(now()); -} - -int second(time_t t) { // the second for the given time - refreshCache(t); - return tm.Second; -} - -int day(){ - return(day(now())); -} - -int day(time_t t) { // the day for the given time (0-6) - refreshCache(t); - return tm.Day; -} - -int weekday() { // Sunday is day 1 - return weekday(now()); -} - -int weekday(time_t t) { - refreshCache(t); - return tm.Wday; -} - -int month(){ - return month(now()); -} - -int month(time_t t) { // the month for the given time - refreshCache(t); - return tm.Month; -} - -int year() { // as in Processing, the full four digit year: (2009, 2010 etc) - return year(now()); -} - -int year(time_t t) { // the year for the given time - refreshCache(t); - return tmYearToCalendar(tm.Year); -} - -/*============================================================================*/ -/* functions to convert to and from system time */ -/* These are for interfacing with time services and are not normally needed in a sketch */ - -// leap year calculator expects year argument as years offset from 1970 -#define LEAP_YEAR(Y) ( ((1970+(Y))>0) && !((1970+(Y))%4) && ( ((1970+(Y))%100) || !((1970+(Y))%400) ) ) - -static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 - -void breakTime(time_t timeInput, tmElements_t &tm){ -// break the given time_t into time components -// this is a more compact version of the C library localtime function -// note that year is offset from 1970 !!! - - uint8_t year; - uint8_t month, monthLength; - uint32_t time; - unsigned long days; - - time = (uint32_t)timeInput; - tm.Second = time % 60; - time /= 60; // now it is minutes - tm.Minute = time % 60; - time /= 60; // now it is hours - tm.Hour = time % 24; - time /= 24; // now it is days - tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 - - year = 0; - days = 0; - while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { - year++; - } - tm.Year = year; // year is offset from 1970 - - days -= LEAP_YEAR(year) ? 366 : 365; - time -= days; // now it is days in this year, starting at 0 - - days=0; - month=0; - monthLength=0; - for (month=0; month<12; month++) { - if (month==1) { // february - if (LEAP_YEAR(year)) { - monthLength=29; - } else { - monthLength=28; - } - } else { - monthLength = monthDays[month]; - } - - if (time >= monthLength) { - time -= monthLength; - } else { - break; - } - } - tm.Month = month + 1; // jan is month 1 - tm.Day = time + 1; // day of month -} - -time_t makeTime(const tmElements_t &tm){ -// assemble time elements into time_t -// note year argument is offset from 1970 (see macros in time.h to convert to other formats) -// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 - - int i; - uint32_t seconds; - - // seconds from 1970 till 1 jan 00:00:00 of the given year - seconds= tm.Year*(SECS_PER_DAY * 365); - for (i = 0; i < tm.Year; i++) { - if (LEAP_YEAR(i)) { - seconds += SECS_PER_DAY; // add extra days for leap years - } - } - - // add days for this year, months start from 1 - for (i = 1; i < tm.Month; i++) { - if ( (i == 2) && LEAP_YEAR(tm.Year)) { - seconds += SECS_PER_DAY * 29; - } else { - seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 - } - } - seconds+= (tm.Day-1) * SECS_PER_DAY; - seconds+= tm.Hour * SECS_PER_HOUR; - seconds+= tm.Minute * SECS_PER_MIN; - seconds+= tm.Second; - return (time_t)seconds; -} -/*=====================================================*/ -/* Low level system time functions */ - -static uint32_t sysTime = 0; -static uint32_t prevMillis = 0; -static uint32_t nextSyncTime = 0; -static timeStatus_t Status = timeNotSet; - -getExternalTime getTimePtr; // pointer to external sync function -//setExternalTime setTimePtr; // not used in this version - -#ifdef TIME_DRIFT_INFO // define this to get drift data -time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync -#endif - - -time_t now() { - // calculate number of seconds passed since last call to now() - while (millis() - prevMillis >= 1000) { - // millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference - sysTime++; - prevMillis += 1000; -#ifdef TIME_DRIFT_INFO - sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift -#endif - } - if (nextSyncTime <= sysTime) { - if (getTimePtr != 0) { - time_t t = getTimePtr(); - if (t != 0) { - setTime(t); - } else { - nextSyncTime = sysTime + syncInterval; - Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync; - } - } - } - return (time_t)sysTime; -} - -void setTime(time_t t) { -#ifdef TIME_DRIFT_INFO - if(sysUnsyncedTime == 0) - sysUnsyncedTime = t; // store the time of the first call to set a valid Time -#endif - - sysTime = (uint32_t)t; - nextSyncTime = (uint32_t)t + syncInterval; - Status = timeSet; - prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) -} - -void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ - // year can be given as full four digit year or two digts (2010 or 10 for 2010); - //it is converted to years since 1970 - if( yr > 99) - yr = yr - 1970; - else - yr += 30; - tm.Year = yr; - tm.Month = mnth; - tm.Day = dy; - tm.Hour = hr; - tm.Minute = min; - tm.Second = sec; - setTime(makeTime(tm)); -} - -void adjustTime(long adjustment) { - sysTime += adjustment; -} - -// indicates if time has been set and recently synchronized -timeStatus_t timeStatus() { - now(); // required to actually update the status - return Status; -} - -void setSyncProvider( getExternalTime getTimeFunction){ - getTimePtr = getTimeFunction; - nextSyncTime = sysTime; - now(); // this will sync the clock -} - -void setSyncInterval(time_t interval){ // set the number of seconds between re-sync - syncInterval = (uint32_t)interval; - nextSyncTime = sysTime + syncInterval; -} diff --git a/lib/Time/TimeLib.h b/lib/Time/TimeLib.h deleted file mode 100644 index b587046..0000000 --- a/lib/Time/TimeLib.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - time.h - low level time and date functions -*/ - -/* - July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this) - - fixed daysToTime_t macro (thanks maniacbug) -*/ - -#ifndef _Time_h -#ifdef __cplusplus -#define _Time_h - -#include -#ifndef __AVR__ -#include // for __time_t_defined, but avr libc lacks sys/types.h -#endif - - -#if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc -typedef unsigned long time_t; -#endif - - -// This ugly hack allows us to define C++ overloaded functions, when included -// from within an extern "C", as newlib's sys/stat.h does. Actually it is -// intended to include "time.h" from the C library (on ARM, but AVR does not -// have that file at all). On Mac and Windows, the compiler will find this -// "Time.h" instead of the C library "time.h", so we may cause other weird -// and unpredictable effects by conflicting with the C library header "time.h", -// but at least this hack lets us define C++ functions as intended. Hopefully -// nothing too terrible will result from overriding the C library header?! -extern "C++" { -typedef enum {timeNotSet, timeNeedsSync, timeSet -} timeStatus_t ; - -typedef enum { - dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday -} timeDayOfWeek_t; - -typedef enum { - tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields -} tmByteFields; - -typedef struct { - uint8_t Second; - uint8_t Minute; - uint8_t Hour; - uint8_t Wday; // day of week, sunday is day 1 - uint8_t Day; - uint8_t Month; - uint8_t Year; // offset from 1970; -} tmElements_t, TimeElements, *tmElementsPtr_t; - -//convenience macros to convert to and from tm years -#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year -#define CalendarYrToTm(Y) ((Y) - 1970) -#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000 -#define y2kYearToTm(Y) ((Y) + 30) - -typedef time_t(*getExternalTime)(); -//typedef void (*setExternalTime)(const time_t); // not used in this version - - -/*==============================================================================*/ -/* Useful Constants */ -#define SECS_PER_MIN ((time_t)(60UL)) -#define SECS_PER_HOUR ((time_t)(3600UL)) -#define SECS_PER_DAY ((time_t)(SECS_PER_HOUR * 24UL)) -#define DAYS_PER_WEEK ((time_t)(7UL)) -#define SECS_PER_WEEK ((time_t)(SECS_PER_DAY * DAYS_PER_WEEK)) -#define SECS_PER_YEAR ((time_t)(SECS_PER_DAY * 365UL)) // TODO: ought to handle leap years -#define SECS_YR_2000 ((time_t)(946684800UL)) // the time at the start of y2k - -/* Useful Macros for getting elapsed time */ -#define numberOfSeconds(_time_) ((_time_) % SECS_PER_MIN) -#define numberOfMinutes(_time_) (((_time_) / SECS_PER_MIN) % SECS_PER_MIN) -#define numberOfHours(_time_) (((_time_) % SECS_PER_DAY) / SECS_PER_HOUR) -#define dayOfWeek(_time_) ((((_time_) / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday -#define elapsedDays(_time_) ((_time_) / SECS_PER_DAY) // this is number of days since Jan 1 1970 -#define elapsedSecsToday(_time_) ((_time_) % SECS_PER_DAY) // the number of seconds since last midnight -// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 -// Always set the correct time before setting alarms -#define previousMidnight(_time_) (((_time_) / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day -#define nextMidnight(_time_) (previousMidnight(_time_) + SECS_PER_DAY) // time at the end of the given day -#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY)) // note that week starts on day 1 -#define previousSunday(_time_) ((_time_) - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time -#define nextSunday(_time_) (previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time - - -/* Useful Macros for converting elapsed time to a time_t */ -#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN) -#define hoursToTime_t ((H)) ( (H) * SECS_PER_HOUR) -#define daysToTime_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011 -#define weeksToTime_t ((W)) ( (W) * SECS_PER_WEEK) - -/*============================================================================*/ -/* time and date functions */ -int hour(); // the hour now -int hour(time_t t); // the hour for the given time -int hourFormat12(); // the hour now in 12 hour format -int hourFormat12(time_t t); // the hour for the given time in 12 hour format -uint8_t isAM(); // returns true if time now is AM -uint8_t isAM(time_t t); // returns true the given time is AM -uint8_t isPM(); // returns true if time now is PM -uint8_t isPM(time_t t); // returns true the given time is PM -int minute(); // the minute now -int minute(time_t t); // the minute for the given time -int second(); // the second now -int second(time_t t); // the second for the given time -int day(); // the day now -int day(time_t t); // the day for the given time -int weekday(); // the weekday now (Sunday is day 1) -int weekday(time_t t); // the weekday for the given time -int month(); // the month now (Jan is month 1) -int month(time_t t); // the month for the given time -int year(); // the full four digit year: (2009, 2010 etc) -int year(time_t t); // the year for the given time - -time_t now(); // return the current time as seconds since Jan 1 1970 -void setTime(time_t t); -void setTime(int hr,int min,int sec,int day, int month, int yr); -void adjustTime(long adjustment); - -/* date strings */ -#define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null) -char* monthStr(uint8_t month); -char* dayStr(uint8_t day); -char* monthShortStr(uint8_t month); -char* dayShortStr(uint8_t day); - -/* time sync functions */ -timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized -void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider -void setSyncInterval(time_t interval); // set the number of seconds between re-sync - -/* low level functions to convert to and from system time */ -void breakTime(time_t time, tmElements_t &tm); // break time_t into elements -time_t makeTime(const tmElements_t &tm); // convert time elements into time_t - -} // extern "C++" -#endif // __cplusplus -#endif /* _Time_h */ - diff --git a/lib/Time/keywords.txt b/lib/Time/keywords.txt deleted file mode 100644 index 073f8f8..0000000 --- a/lib/Time/keywords.txt +++ /dev/null @@ -1,34 +0,0 @@ -####################################### -# Syntax Coloring Map For Time -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### -time_t KEYWORD1 -####################################### -# Methods and Functions (KEYWORD2) -####################################### -now KEYWORD2 -second KEYWORD2 -minute KEYWORD2 -hour KEYWORD2 -day KEYWORD2 -month KEYWORD2 -year KEYWORD2 -isAM KEYWORD2 -isPM KEYWORD2 -weekday KEYWORD2 -setTime KEYWORD2 -adjustTime KEYWORD2 -setSyncProvider KEYWORD2 -setSyncInterval KEYWORD2 -timeStatus KEYWORD2 -TimeLib KEYWORD2 -####################################### -# Instances (KEYWORD2) -####################################### - -####################################### -# Constants (LITERAL1) -####################################### diff --git a/lib/Time/library.json b/lib/Time/library.json deleted file mode 100644 index b181e78..0000000 --- a/lib/Time/library.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "Time", - "description": "Time keeping library", - "keywords": "Time, date, hour, minute, second, day, week, month, year, RTC", - "authors": [ - { - "name": "Michael Margolis" - }, - { - "name": "Paul Stoffregen", - "email": "paul@pjrc.com", - "url": "http://www.pjrc.com", - "maintainer": true - } - ], - "repository": { - "type": "git", - "url": "https://github.com/PaulStoffregen/Time" - }, - "version": "1.6.1", - "homepage": "http://playground.arduino.cc/Code/Time", - "frameworks": "Arduino", - "examples": [ - "examples/*/*.ino" - ] -} diff --git a/lib/Time/library.properties b/lib/Time/library.properties deleted file mode 100644 index 4aa6ad8..0000000 --- a/lib/Time/library.properties +++ /dev/null @@ -1,11 +0,0 @@ -name=Time -version=1.6.1 -author=Michael Margolis -maintainer=Paul Stoffregen -sentence=Timekeeping functionality for Arduino -paragraph=Date and Time functions, with provisions to synchronize to external time sources like GPS and NTP (Internet). This library is often used together with TimeAlarms and DS1307RTC. -category=Timing -url=http://playground.arduino.cc/Code/Time/ -includes=TimeLib.h -architectures=* - diff --git a/src/NTPupdate.cpp b/src/NTPupdate.cpp index c0fa862..a2c2939 100644 --- a/src/NTPupdate.cpp +++ b/src/NTPupdate.cpp @@ -54,12 +54,7 @@ void NTPupdate() { time_t currentTime = getNtpTime(); if (currentTime) { - rtc.setTime(currentTime); - if(rx_rtc_avail) { - RX8010SJ::DateTime rx_currenttime = RX8010SJ::DateTime(); - timeToDateTime(currentTime, &rx_currenttime); - rx_rtc.writeDateTime(rx_currenttime); - } + set_time(currentTime); rtcset = true; NTPupdated = true; radio.rds.ctupdate = false; diff --git a/src/TEF6686.cpp b/src/TEF6686.cpp index deddd40..07015a7 100644 --- a/src/TEF6686.cpp +++ b/src/TEF6686.cpp @@ -1,13 +1,11 @@ #include "TEF6686.h" #include #include -#include #include #include "constants.h" #include "utils.h" -unsigned long rdstimer = 0; -unsigned long bitStartTime = 0; +uint8_t dropped_groups = 0; bool lastBitState = false; uint16_t TEF6686::getBlockA(void) { @@ -25,13 +23,13 @@ void TEF6686::TestAFEON() { setMute(); for (int x = 0; x < af_counter; x++) { timing = 0; - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 3, af[x].frequency); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 3, af[x].frequency); while (timing == 0 && !bitRead(timing, 15)) { devTEF_Radio_Get_Quality_Status(&status, &aflevel, &afusn, &afwam, &afoffset, NULL, NULL, NULL); timing = lowByte(status); } if (afoffset > -125 || afoffset < 125) { - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 4, af[x].frequency); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 4, af[x].frequency); delay(187); devTEF_Radio_Get_RDS_Status(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); @@ -47,7 +45,7 @@ void TEF6686::TestAFEON() { } } } - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 4, currentfreq); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 4, currentfreq); setUnMute(); } @@ -62,7 +60,7 @@ uint16_t TEF6686::TestAF() { for (int x = 0; x < af_counter; x++) { timing = 0; - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 3, af[x].frequency); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 3, af[x].frequency); while (timing == 0 && !bitRead(timing, 15)) { devTEF_Radio_Get_Quality_Status(&status, &aflevel, &afusn, &afwam, &afoffset, NULL, NULL, NULL); timing = lowByte(status); @@ -82,7 +80,7 @@ uint16_t TEF6686::TestAF() { } if (af_counter != 0 && af[highestIndex].afvalid && af[highestIndex].score > (currentlevel - currentusn - currentwam) && (af[highestIndex].score - (currentlevel - currentusn - currentwam)) >= 70) { - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 4, af[highestIndex].frequency); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 4, af[highestIndex].frequency); delay(187); devTEF_Radio_Get_RDS_Status(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); if (bitRead(rds.rdsStat, 9)) { @@ -97,9 +95,9 @@ uint16_t TEF6686::TestAF() { af_counter = 0; } else { af[highestIndex].afvalid = false; - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 4, currentfreq); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 4, currentfreq); } - } else devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 4, currentfreq); + } else devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 4, currentfreq); } } return currentfreq; @@ -113,10 +111,11 @@ void TEF6686::init(byte TEF) { uint32_t clock = 12000000; #ifndef DEEPELEC_DP_66X - int xtalADC = analogRead(15); - if (xtalADC < XTAL_0V_ADC + XTAL_ADC_TOL) clock = 9216000; - else if (xtalADC > XTAL_1V_ADC - XTAL_ADC_TOL && xtalADC < XTAL_1V_ADC + XTAL_ADC_TOL); - else if (xtalADC > XTAL_2V_ADC - XTAL_ADC_TOL && xtalADC < XTAL_2V_ADC + XTAL_ADC_TOL) clock = 55466670; + int xtalMV = analogReadMilliVolts(15); + + if (xtalMV < 0 + XTAL_MV_TOL) clock = 9216000; + else if (xtalMV > 1000 - XTAL_MV_TOL && xtalMV < 1000 + XTAL_MV_TOL); + else if (xtalMV > 2000 - XTAL_MV_TOL && xtalMV < 2000 + XTAL_MV_TOL) clock = 55466670; else clock = 4000000; #endif @@ -124,26 +123,26 @@ void TEF6686::init(byte TEF) { Tuner_Patch(TEF); // Start the firmware - devTEF_Set_Cmd(TEF_INIT, 0, 3); + devTEF_Set_Cmd(TEF_INIT, 0, 0); while(devTEF_APPL_Get_Operation_Status() != 1) delay(5); // Wait for it to load - if(clock != 9216000) devTEF_Set_Cmd(TEF_APPL, Cmd_Set_ReferenceClock, 9, (clock >> 16) & 0xffff, clock & 0xffff, (clock == 55466670) ? 1 : 0); - devTEF_Set_Cmd(TEF_APPL, Cmd_Set_Activate, 5, 1); // Setup done, start radio + if(clock != 9216000) devTEF_Set_Cmd(TEF_APPL, Cmd_Set_ReferenceClock, 6, (clock >> 16) & 0xffff, clock & 0xffff, (clock == 55466670) ? 1 : 0); + devTEF_Set_Cmd(TEF_APPL, Cmd_Set_Activate, 2, 1); // Setup done, start radio while(devTEF_APPL_Get_Operation_Status() != 2) delay(5); // Wait for it to start - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Mph, 9, 0, 360, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Max, 7, 0, 4000); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_LowCut_Max, 7, 0, 100); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Time, 11, 60, 120, 100, 200); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Time, 11, 500, 2000, 200, 200); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Level, 9, 0, 600, 240); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Noise, 9, 0, 160, 140); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Mph, 9, 0, 160, 140); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Max, 7, 0, 4000); - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Ana_Out, 7, 128, 1); - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Output_Source, 7, 128, 224); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Mph, 6, 0, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Max, 4, 0, 4000); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_LowCut_Max, 4, 0, 100); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Time, 8, 60, 120, 100, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Time, 8, 500, 2000, 200, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Level, 6, 0, 600, 240); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Noise, 6, 0, 160, 140); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Mph, 6, 0, 160, 140); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Max, 4, 0, 4000); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Ana_Out, 4, 128, 1); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Output_Source, 4, 128, 224); } void TEF6686::getIdentification(uint16_t *device, uint16_t *hw_version, uint16_t *sw_version) { @@ -156,73 +155,73 @@ void TEF6686::getIdentification(uint16_t *device, uint16_t *hw_version, uint16_t } void TEF6686::power(bool mode) { - devTEF_Set_Cmd(TEF_APPL, Cmd_Set_OperationMode, 5, mode); - if (mode == 0) devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 1, 10000); + devTEF_Set_Cmd(TEF_APPL, Cmd_Set_OperationMode, 2, mode); + if (mode == 0) devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 1, 10000); } void TEF6686::extendBW(bool yesno) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Bandwidth_Options, 5, (yesno ? 400 : 950)); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Bandwidth_Options, 2, (yesno ? 400 : 950)); } void TEF6686::SetFreq(uint16_t frequency) { - devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 7, 4, frequency); + devTEF_Set_Cmd(TEF_FM, Cmd_Tune_To, 4, 4, frequency); currentfreq = ((frequency + 5) / 10) * 10; currentfreq2 = frequency; } void TEF6686::SetFreqAM(uint16_t frequency) { - devTEF_Set_Cmd(TEF_AM, Cmd_Tune_To, 7, 1, frequency); + devTEF_Set_Cmd(TEF_AM, Cmd_Tune_To, 4, 1, frequency); } void TEF6686::setOffset(int8_t offset) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_LevelOffset, 5, (offset * 10) - 70); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_LevelOffset, 2, (offset * 10) - 70); } void TEF6686::setAMOffset(int8_t offset) { - devTEF_Set_Cmd(TEF_AM, Cmd_Set_LevelOffset, 5, (offset * 10) - 70); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_LevelOffset, 2, (offset * 10) - 70); } void TEF6686::setFMBandw(uint16_t bandwidth) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Bandwidth, 7, 0, bandwidth * 10); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Bandwidth, 4, 0, bandwidth * 10); } void TEF6686::setAMBandw(uint16_t bandwidth) { - devTEF_Set_Cmd(TEF_AM, Cmd_Set_Bandwidth, 7, 0, bandwidth * 10); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_Bandwidth, 4, 0, bandwidth * 10); } void TEF6686::setAMCoChannel(uint16_t start, uint8_t level) { uint8_t mode = 1; if(start == 0) mode = 0; - devTEF_Set_Cmd(TEF_AM, Cmd_Set_CoChannelDet, 11, mode, 2, start * 10, 1000, level); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_CoChannelDet, 8, mode, 2, start * 10, 1000, level); } void TEF6686::setSoftmuteAM(uint8_t mode) { - devTEF_Set_Cmd(TEF_AM, Cmd_Set_Softmute_Max, 7, mode, 250); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_Softmute_Max, 4, mode, 250); } void TEF6686::setSoftmuteFM(uint8_t mode) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Softmute_Max, 7, mode, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Softmute_Max, 4, mode, 200); } void TEF6686::setAMNoiseBlanker(uint16_t start) { - devTEF_Set_Cmd(TEF_AM, Cmd_Set_NoiseBlanker, 7, (start == 0) ? 0 : 1, (start == 0) ? 1000 : start * 10); - devTEF_Set_Cmd(TEF_AM, Cmd_Set_NoiseBlanker_Audio, 7, (start == 0) ? 0 : 1, 1000); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_NoiseBlanker, 4, (start == 0) ? 0 : 1, (start == 0) ? 1000 : start * 10); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_NoiseBlanker_Audio, 4, (start == 0) ? 0 : 1, 1000); } void TEF6686::setAMAttenuation(uint16_t start) { - devTEF_Set_Cmd(TEF_AM, Cmd_Set_Antenna, 5, start * 10); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_Antenna, 2, start * 10); } void TEF6686::setFMABandw() { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Bandwidth, 7, 1, 3110); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Bandwidth, 4, 1, 3110); } void TEF6686::setiMS(bool mph) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_MphSuppression, 5, mph); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_MphSuppression, 2, mph); } void TEF6686::setEQ(bool eq) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_ChannelEqualizer, 5, eq); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_ChannelEqualizer, 2, eq); } bool TEF6686::getStereoStatus() { @@ -233,109 +232,109 @@ bool TEF6686::getStereoStatus() { } void TEF6686::setMono(bool mono) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Min, 7, mono ? 2 : 0); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Min, 4, mono ? 2 : 0); } void TEF6686::setVolume(int8_t volume) { - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Volume, 5, volume * 10); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Volume, 2, volume * 10); } void TEF6686::setMute() { mute = true; - if (mpxmode) devTEF_Set_Cmd(TEF_FM, Cmd_Set_Specials, 5, 0); - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Mute, 5, 1); + if (mpxmode) devTEF_Set_Cmd(TEF_FM, Cmd_Set_Specials, 2, 0); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Mute, 2, 1); } void TEF6686::setUnMute() { mute = false; - if (mpxmode) devTEF_Set_Cmd(TEF_FM, Cmd_Set_Specials, 5, 1); - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Mute, 5, 0); + if (mpxmode) devTEF_Set_Cmd(TEF_FM, Cmd_Set_Specials, 2, 1); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Mute, 2, 0); } void TEF6686::setAGC(uint8_t agc) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_RFAGC, 7, agc * 10, 0); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_RFAGC, 4, agc * 10, 0); } void TEF6686::setAMAGC(uint8_t agc) { - devTEF_Set_Cmd(TEF_AM, Cmd_Set_RFAGC, 7, agc * 10, 0); + devTEF_Set_Cmd(TEF_AM, Cmd_Set_RFAGC, 4, agc * 10, 0); } void TEF6686::setDeemphasis(uint8_t timeconstant) { switch (timeconstant) { - case 1: devTEF_Set_Cmd(TEF_FM, Cmd_Set_Deemphasis, 5, 500); break; - case 2: devTEF_Set_Cmd(TEF_FM, Cmd_Set_Deemphasis, 5, 750); break; - default: devTEF_Set_Cmd(TEF_FM, Cmd_Set_Deemphasis, 5, 0); break; + case 1: devTEF_Set_Cmd(TEF_FM, Cmd_Set_Deemphasis, 2, 500); break; + case 2: devTEF_Set_Cmd(TEF_FM, Cmd_Set_Deemphasis, 2, 750); break; + default: devTEF_Set_Cmd(TEF_FM, Cmd_Set_Deemphasis, 2, 0); break; } } void TEF6686::setAudio(uint8_t audio) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Specials, 5, audio); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Specials, 2, audio); mpxmode = (audio != 0); } void TEF6686::setFMSI(uint8_t mode) { if(mode > 2) mode = 2; if(mode < 1) mode = 1; - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StereoImprovement, 5, mode-1); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StereoImprovement, 2, mode-1); } void TEF6686::setFMSI_Time(uint16_t attack, uint16_t decay) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StBandBlend_Time, 7, attack, decay); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StBandBlend_Time, 4, attack, decay); } void TEF6686::setFMSI_Gain(uint16_t band1, uint16_t band2, uint16_t band3, uint16_t band4) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StBandBlend_Gain, 11, band1 * 10, band2 * 10, band3 * 10, band4 * 10); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StBandBlend_Gain, 8, band1 * 10, band2 * 10, band3 * 10, band4 * 10); } void TEF6686::setFMSI_Bias(int16_t band1, int16_t band2, int16_t band3, int16_t band4) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StBandBlend_Bias, 11, band1 - 250, band2 - 250, band3 - 250, band4 - 250); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StBandBlend_Bias, 8, band1 - 250, band2 - 250, band3 - 250, band4 - 250); } void TEF6686::setFMNoiseBlanker(uint16_t start) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_NoiseBlanker, 7, (start == 0) ? 0 : 1, (start == 0) ? 1000 : (start * 10)); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_NoiseBlanker, 4, (start == 0) ? 0 : 1, (start == 0) ? 1000 : (start * 10)); } void TEF6686::setStereoLevel(uint8_t start) { if (start == 0) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Level, 9, 0, start * 10, 60); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Noise, 9, 0, 240, 200); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Mph, 9, 0, 240, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Level, 6, 0, start * 10, 60); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Noise, 6, 0, 240, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Mph, 6, 0, 240, 200); } else { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Level, 9, 3, start * 10, 60); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Noise, 9, 3, 240, 200); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Mph, 9, 3, 240, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Level, 6, 3, start * 10, 60); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Noise, 6, 3, 240, 200); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Stereo_Mph, 6, 3, 240, 200); } } void TEF6686::setHighCutOffset(uint8_t start) { if (start == 0) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Level, 9, 0, start * 10, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Noise, 9, 0, 360, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Mph, 9, 0, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Level, 6, 0, start * 10, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Noise, 6, 0, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Mph, 6, 0, 360, 300); } else { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Level, 9, 3, start * 10, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Noise, 9, 3, 360, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Mph, 9, 3, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Level, 6, 3, start * 10, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Noise, 6, 3, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Mph, 6, 3, 360, 300); } } void TEF6686::setHighCutLevel(uint16_t limit) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Max, 7, 1, limit * 100); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_Highcut_Max, 4, 1, limit * 100); } void TEF6686::setStHiBlendLevel(uint16_t limit) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Max, 7, 1, limit * 100); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Max, 4, 1, limit * 100); } void TEF6686::setStHiBlendOffset(uint8_t start) { if (start == 0) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Level, 9, 0, start * 10, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Noise, 9, 0, 360, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Mph, 9, 0, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Level, 6, 0, start * 10, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Noise, 6, 0, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Mph, 6, 0, 360, 300); } else { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Level, 9, 3, start * 10, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Noise, 9, 3, 360, 300); - devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Mph, 9, 3, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Level, 6, 3, start * 10, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Noise, 6, 3, 360, 300); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_StHiBlend_Mph, 6, 3, 360, 300); } } @@ -360,23 +359,19 @@ void TEF6686::getStatusAM(int16_t *level, uint16_t *noise, uint16_t *cochannel, void TEF6686::readRDS(byte showrdserrors) { if(rds.filter && ps_process) devTEF_Radio_Get_RDS_Status(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); else { - if(millis() >= rdstimer + 87) { - rdstimer += 87; + for(int i = 0; i < 3; i++) { devTEF_Radio_Get_RDS_Data(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); - - if(bitRead(rds.rdsStat, 14)) { - for (int i = 0; i < 22; i++) devTEF_Radio_Get_RDS_Data(&rds.rdsStat, &rds.rdsA, &rds.rdsB, &rds.rdsC, &rds.rdsD, &rds.rdsErr); - } + delay(2); + if(bitRead(rds.rdsStat, 15)) break; } } - if(bitRead(rds.rdsStat, 9)) { rds.hasRDS = true; - bitStartTime = 0; + dropped_groups = 0; } else { - if(bitStartTime == 0) bitStartTime = millis(); - else if(millis() - bitStartTime >= 87) rds.hasRDS = false; + if(dropped_groups > 7) rds.hasRDS = false; + dropped_groups++; return; // No sync means no data, ever! Unless sync status changes of course } @@ -1215,18 +1210,18 @@ void TEF6686::readRDS(byte showrdserrors) { if (rds.rdsD == 0x4BD7) { rds.hasRTplus = true; - rtplusblock = ((rds.rdsB & 0x1F) >> 1) * 2; + rtplusblock = rds.rdsB & 0x1E; } if (rds.rdsD == 0x0093) { rds.hasDABAF = true; - DABAFblock = ((rds.rdsB & 0x1F) >> 1) * 2; + DABAFblock = rds.rdsB & 0x1E; } if (rds.rdsD == 0x6552) { _hasEnhancedRT = true; - eRTblock = ((rds.rdsB & 0x1F) >> 1) * 2; - eRTcoding = bitRead(rds.rdsC, 0); + eRTblock = rds.rdsB & 0x1E; + eRTcoding = rds.rdsC & 1; } } } break; @@ -1250,11 +1245,11 @@ void TEF6686::readRDS(byte showrdserrors) { if ((M + 2 - (12 * J)) < 13) month = M + 2 - (12 * J); if ((100 * (C - 49) + Y + J) > 2022) year = 100 * (C - 49) + Y + J; - hour = ((rds.rdsD >> 12) & 0xf) | ((rds.rdsC << 4) & 0x10); - timeoffset = rds.rdsD & 0x001f; + hour = ((rds.rdsD >> 12) & 0xF) | ((rds.rdsC << 4) & 0x10); + timeoffset = rds.rdsD & 0x1F; if (bitRead(rds.rdsD, 5)) timeoffset *= -1; timeoffset *= 1800; - minute = (rds.rdsD & 0x0fc0) >> 6; + minute = (rds.rdsD & 0xFC0) >> 6; if (year < 2026 || hour > 23 || minute > 59 || timeoffset > 55800 || timeoffset < -55800) break; @@ -1279,8 +1274,7 @@ void TEF6686::readRDS(byte showrdserrors) { if (!NTPupdated) { time_t corrected_time = rds_utc_time - (current_correction / 2); - rtc.setTime(corrected_time); - sync_to_rx_rtc(); + set_time(corrected_time); } } else rds.hasCT = false; lastrdstime = rdstime; @@ -1562,7 +1556,7 @@ void TEF6686::readRDS(byte showrdserrors) { } void TEF6686::clearRDS(bool fullsearchrds) { - devTEF_Set_Cmd(TEF_FM, Cmd_Set_RDS, 9, fullsearchrds ? 3 : 1, 1, 0); + devTEF_Set_Cmd(TEF_FM, Cmd_Set_RDS, 6, fullsearchrds ? 3 : 1, 1, 0); rds.piBuffer.clear(); rds.stationName = rds.stationText = rds.stationNameLong = ""; rds.PTYN = rds.stationText32 = rds.RTContent1 = rds.RTContent2 = "";; @@ -1648,7 +1642,7 @@ void TEF6686::clearRDS(bool fullsearchrds) { } void TEF6686::tone(uint16_t time, int16_t amplitude, uint16_t frequency) { - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Mute, 5, 0); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Mute, 2, 0); devTEF_Radio_Set_Wavegen(1, amplitude, frequency); delay(time); devTEF_Radio_Set_Wavegen(0, 0, 0); @@ -1697,10 +1691,10 @@ void TEF6686::RDScharConverter(const char* input, wchar_t* output, size_t size, case 0x9B: output[i] = L'ç'; break; case 0x9C: output[i] = L'ş'; break; case 0x9D: output[i] = L'ǧ'; break; - case 0x9E: output[i] = L'ı'; break; + case 0x9E: output[i] = L'\x131'; break; case 0x9F: output[i] = L'ij'; break; case 0xA0: output[i] = L'ª'; break; - case 0xA1: output[i] = L'α'; break; + case 0xA1: output[i] = L'\x3b1'; break; case 0xA2: output[i] = L'©'; break; case 0xA3: output[i] = L'‰'; break; case 0xA4: output[i] = L'Ǧ'; break; diff --git a/src/Tuner_Drv_Lithio.cpp b/src/Tuner_Drv_Lithio.cpp index 40fc074..30881e0 100644 --- a/src/Tuner_Drv_Lithio.cpp +++ b/src/Tuner_Drv_Lithio.cpp @@ -10,14 +10,14 @@ void devTEF_Set_Cmd(TEF_MODULE module, uint8_t cmd, uint16_t len, ...) { buf[1] = cmd; buf[2] = 1; - for (i = 3; i < len; i++) { + for (i = 0; i < len; i++) { temp = va_arg(vArgs, int); - buf[i++] = High_16bto8b(temp); - buf[i] = Low_16bto8b(temp); + buf[3 + i++] = High_16bto8b(temp); + buf[3 + i] = Low_16bto8b(temp); } va_end(vArgs); - Tuner_WriteBuffer(buf, len); + Tuner_WriteBuffer(buf, len + 3); } bool devTEF_Get_Cmd(TEF_MODULE module, uint8_t cmd, uint8_t *receive, uint16_t len) { @@ -32,25 +32,10 @@ bool devTEF_Get_Cmd(TEF_MODULE module, uint8_t cmd, uint8_t *receive, uint16_t l uint8_t devTEF_APPL_Get_Operation_Status() { uint8_t buf[2]; - while(!devTEF_Get_Cmd(TEF_APPL, Cmd_Get_Operation_Status, buf, sizeof(buf))) delay(1); + while(!devTEF_Get_Cmd(TEF_APPL, Cmd_Get_Operation_Status, buf, sizeof(buf))) delay(2); return Convert8bto16b(buf); } -bool devTEF_Radio_Get_Processing_Status(uint16_t *highcut, uint16_t *stereo, uint16_t *sthiblend, uint8_t *stband_1, uint8_t *stband_2, uint8_t *stband_3, uint8_t *stband_4) { - uint8_t buf[12]; - uint16_t r = devTEF_Get_Cmd(TEF_FM, Cmd_Get_Processing_Status, buf, sizeof(buf)); - *highcut = Convert8bto16b(buf + 2) / 10; - *stereo = Convert8bto16b(buf + 4) / 10; - *sthiblend = Convert8bto16b(buf + 6) / 10; - uint16_t stband_1_2 = Convert8bto16b(buf + 8); - uint16_t stband_3_4 = Convert8bto16b(buf + 10); - *stband_1 = High_16bto8b(stband_1_2); - *stband_2 = Low_16bto8b(stband_1_2); - *stband_3 = High_16bto8b(stband_3_4); - *stband_4 = Low_16bto8b(stband_3_4); - return r; -} - void devTEF_Radio_Get_Quality_Status(uint16_t *status, int16_t *level, uint16_t *usn, uint16_t *wam, int16_t *offset, uint16_t *bandwidth, uint16_t *mod, int8_t *snr) { uint8_t buf[14]; devTEF_Get_Cmd(TEF_FM, Cmd_Get_Quality_Data, buf, sizeof(buf)); @@ -77,16 +62,15 @@ void devTEF_Radio_Get_RDS_Status(uint16_t *status, uint16_t *A_block, uint16_t * if(dec_error != NULL) *dec_error = Convert8bto16b(buf + 10); } -bool devTEF_Radio_Get_RDS_Data(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error) { +void devTEF_Radio_Get_RDS_Data(uint16_t *status, uint16_t *A_block, uint16_t *B_block, uint16_t *C_block, uint16_t *D_block, uint16_t *dec_error) { uint8_t buf[12]; - uint8_t r = devTEF_Get_Cmd(TEF_FM, Cmd_Get_RDS_Data, buf, sizeof(buf)); - *status = Convert8bto16b(buf); - *A_block = Convert8bto16b(buf + 2); - *B_block = Convert8bto16b(buf + 4); - *C_block = Convert8bto16b(buf + 6); - *D_block = Convert8bto16b(buf + 8); - *dec_error = Convert8bto16b(buf + 10); - return r; + devTEF_Get_Cmd(TEF_FM, Cmd_Get_RDS_Data, buf, sizeof(buf)); + if(status != NULL) *status = Convert8bto16b(buf); + if(A_block != NULL) *A_block = Convert8bto16b(buf + 2); + if(B_block != NULL) *B_block = Convert8bto16b(buf + 4); + if(C_block != NULL) *C_block = Convert8bto16b(buf + 6); + if(D_block != NULL) *D_block = Convert8bto16b(buf + 8); + if(dec_error != NULL) *dec_error = Convert8bto16b(buf + 10); } bool devTEF_Radio_Get_Stereo_Status(uint16_t *status) { @@ -98,7 +82,7 @@ bool devTEF_Radio_Get_Stereo_Status(uint16_t *status) { } void devTEF_Radio_Set_Wavegen(bool mode, int16_t amplitude, uint16_t freq) { - devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Input, 5, mode ? 240 : 0); - if (mode) devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_WaveGen, 15, 5, 0, amplitude * 10, freq, amplitude * 10, freq); - else devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_WaveGen, 15, 0); + devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_Input, 2, mode ? 240 : 0); + if (mode) devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_WaveGen, 12, 5, 0, amplitude * 10, freq, amplitude * 10, freq); + else devTEF_Set_Cmd(TEF_AUDIO, Cmd_Set_WaveGen, 12, 0); } \ No newline at end of file diff --git a/src/Tuner_Interface.cpp b/src/Tuner_Interface.cpp index 8a08cd2..6a2e1f6 100644 --- a/src/Tuner_Interface.cpp +++ b/src/Tuner_Interface.cpp @@ -9,7 +9,7 @@ bool Tuner_WriteBuffer(unsigned char *buf, uint16_t len) { Wire.beginTransmission(TEF668X_ADDRESS); for (uint16_t i = 0; i < len; i++) Wire.write(buf[i]); uint8_t r = Wire.endTransmission(); - if (!Data_Accelerator) delay(1); + if (!Data_Accelerator) delay(2); return (r == 0) ? true : false; } diff --git a/src/logbook.cpp b/src/logbook.cpp index 21aab62..6341a99 100644 --- a/src/logbook.cpp +++ b/src/logbook.cpp @@ -406,9 +406,11 @@ void sendUDPlog() { String CHIP = ""; switch (chipmodel) { case 0: CHIP = "TEF6686"; break; +#ifndef DEEPELEC_DP_66X case 1: CHIP = "TEF6687"; break; case 2: CHIP = "TEF6688"; break; case 3: CHIP = "TEF6689"; break; +#endif } String RTPLUS = ""; diff --git a/src/main.cpp b/src/main.cpp index 668d4d7..2f7e5f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include using fs::FS; #include #include "NTPupdate.h" @@ -252,7 +251,7 @@ void SetTunerPatch() { EEPROM.writeByte(EE_BYTE_TEF, TEF); EEPROM.commit(); Tuner_Reset(); - ESP.restart(); + esp_restart(); } } @@ -1159,11 +1158,12 @@ void setup() { Wire.begin(); Wire.setClock(400000); - delay(5); + delay(3); Serial.begin(115200); + Serial.println(); byte error, address; - for (address = 1; address < 127; address++) { + for (address = 1; address < 108; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); @@ -1175,6 +1175,8 @@ void setup() { Serial.print(" RTC"); rx_rtc_avail = true; } + else if(address == TEF668X_ADDRESS) Serial.print(" TEF"); + else if(address == XL9555_ADDRESS) Serial.print(" GPIO"); Serial.println(" !"); } else if (error == 4) { Serial.print("Unknown error at 0x"); @@ -1182,21 +1184,19 @@ void setup() { Serial.println(address, HEX); } } - Serial.flush(); - Serial.end(); rtc.setTime(0); if(rx_rtc_avail) { - RX8010SJ::DateTime defaulttime = RX8010SJ::DateTime(); - defaulttime.second = 21; - defaulttime.minute = 45; - defaulttime.hour = 11; - defaulttime.dayOfWeek = 6; - defaulttime.dayOfMonth = 11; - defaulttime.month = 1; - defaulttime.year = 26; bool reset = rx_rtc.initModule(); // initModule, not initAdapter, adapter also reinits wire if(reset) { + RX8010SJ::DateTime defaulttime = RX8010SJ::DateTime(); + defaulttime.second = 00; + defaulttime.minute = 00; + defaulttime.hour = 18; + defaulttime.dayOfWeek = 1; + defaulttime.dayOfMonth = 13; + defaulttime.month = 1; + defaulttime.year = 26; Serial.println("RTC reset with defaults"); rx_rtc.writeDateTime(defaulttime); } else { @@ -1205,6 +1205,9 @@ void setup() { } } + Serial.flush(); + Serial.end(); + EEPROM.begin(EE_TOTAL_CNT); loadData(); @@ -1408,7 +1411,7 @@ void setup() { Infoboxprint(textUI(66)); tftPrint(ACENTER, textUI(2), 155, 130, ActiveColor, ActiveColorSmooth, 28); while (digitalRead(ROTARY_BUTTON) == LOW && digitalRead(BWBUTTON) == LOW) delay(50); - ESP.restart(); + esp_restart(); } if (digitalRead(BWBUTTON) == LOW && digitalRead(ROTARY_BUTTON) == HIGH && digitalRead(MODEBUTTON) == LOW && digitalRead(BANDBUTTON) == HIGH) { @@ -1439,7 +1442,7 @@ void setup() { tft.fillScreen(BackgroundColor); tftPrint(ACENTER, textUI(8), 160, 3, PrimaryColor, PrimaryColorSmooth, 28); - tftPrint(ACENTER, "Software " + String(VERSION), 160, 152, PrimaryColor, PrimaryColorSmooth, 16); + tftPrint(ACENTER, "Firmware " + String(VERSION), 160, 152, PrimaryColor, PrimaryColorSmooth, 16); tft.fillRect(120, 230, 16, 6, GreyoutColor); tft.fillRect(152, 230, 16, 6, GreyoutColor); @@ -1492,7 +1495,7 @@ void setup() { tft.fillRect(152, 230, 16, 6, SignificantColor); while (true); } - tftPrint(ACENTER, "Patch: v" + String(TEF), 160, 202, ActiveColor, ActiveColorSmooth, 28); + tftPrint(ACENTER, "Patch: v" + String(TEF) + " HW " + String(hw >> 8) + "." + String(hw & 0xff) + " SW " + String(sw >> 8) + "." + String(sw & 0xff), 160, 202, ActiveColor, ActiveColorSmooth, 16); // Configures the GPIO chip for input in every pin Wire.beginTransmission(XL9555_ADDRESS); @@ -1507,14 +1510,14 @@ void setup() { if (wifi) { tryWiFi(); tft.fillRect(184, 230, 16, 6, PrimaryColor); - delay(2000); + delay(1750); } else { Server.end(); Udp.stop(); tft.fillRect(184, 230, 16, 6, SignificantColor); } - while(digitalRead(ROTARY_BUTTON) == LOW) delay(50); + while(digitalRead(ROTARY_BUTTON) == LOW) delay(75); radio.setVolume(VolSet); radio.setOffset(LevelOffset); @@ -2035,7 +2038,6 @@ void DivdeSWMIBand() { } SWMIBandPos = SW_MI_BAND_GAP; } - } void ToggleSWMIBand(bool frequencyup) { @@ -4044,4 +4046,39 @@ uint8_t doAutoMemory(uint16_t startfreq, uint16_t stopfreq, uint8_t startmem, ui SQ = false; return error; +} + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_task_wdt.h" + +#ifndef ARDUINO_LOOP_STACK_SIZE +#ifndef CONFIG_ARDUINO_LOOP_STACK_SIZE +#define ARDUINO_LOOP_STACK_SIZE 8192 +#else +#define ARDUINO_LOOP_STACK_SIZE CONFIG_ARDUINO_LOOP_STACK_SIZE +#endif +#endif + +TaskHandle_t loopTaskHandle = NULL; + +bool loopTaskWDTEnabled; + +__attribute__((weak)) size_t getArduinoLoopTaskStackSize(void) { + return ARDUINO_LOOP_STACK_SIZE; +} + +void loopTask(void *pvParameters) +{ + setup(); + for(;;) { + if(loopTaskWDTEnabled) esp_task_wdt_reset(); + loop(); + if (serialEventRun) serialEventRun(); + } +} + +extern "C" void app_main() { + initArduino(); + xTaskCreateUniversal(loopTask, "loopTask", getArduinoLoopTaskStackSize(), NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE); } \ No newline at end of file diff --git a/src/rds.cpp b/src/rds.cpp index d8709a1..8b4fc5f 100644 --- a/src/rds.cpp +++ b/src/rds.cpp @@ -1,6 +1,5 @@ #include "rds.h" #include "constants.h" -#include #include "utils.h" String HexStringold; @@ -513,7 +512,7 @@ void showPS() { } void showCT() { - char timeStr[16]; + char timeStr[32]; char dateStr[9]; time_t t = rtc.getEpoch(); @@ -532,8 +531,8 @@ void showCT() { else if (hour > 12) hour -= 12; } - String ampm = (localtm->tm_hour >= 12) ? "PM" : "AM"; - snprintf(timeStr, sizeof(timeStr), "%d:%02d %s", hour, localtm->tm_min, ampm.c_str()); + const char* ampm = (localtm->tm_hour >= 12) ? "PM" : "AM"; + snprintf(timeStr, sizeof(timeStr), "%d:%02d %.2s", hour, localtm->tm_min, ampm); } else { int hour = localtm->tm_hour; if (hour < 0 || hour > 23) hour = 0; diff --git a/src/rtc.cpp b/src/rtc.cpp index a0137fa..87fbdf1 100644 --- a/src/rtc.cpp +++ b/src/rtc.cpp @@ -14,23 +14,8 @@ void timeToDateTime(time_t t, struct RX8010SJ::DateTime* dateTime) { dateTime->hour = timeinfo->tm_hour; dateTime->dayOfWeek = (timeinfo->tm_wday + 6) % 7; dateTime->dayOfMonth = timeinfo->tm_mday; - dateTime->month = timeinfo->tm_mon + 1; // tm_mon is 0-11, convert to 1-12 - dateTime->year = (timeinfo->tm_year + 1900) % 100; // Get last 2 digits -} - -time_t timegm(struct tm *tm) { - // https://linux.die.net/man/3/timegm - time_t ret; - char *tz; - - tz = getenv("TZ"); - setenv("TZ", "", 1); - tzset(); - ret = mktime(tm); - if (tz) setenv("TZ", tz, 1); - else unsetenv("TZ"); - tzset(); - return ret; + dateTime->month = timeinfo->tm_mon + 1; + dateTime->year = (timeinfo->tm_year + 1900) % 100; } time_t dateTimeToTime(const struct RX8010SJ::DateTime* dateTime) { @@ -42,17 +27,19 @@ time_t dateTimeToTime(const struct RX8010SJ::DateTime* dateTime) { timeinfo.tm_mon = dateTime->month - 1; timeinfo.tm_year = dateTime->year + 100; timeinfo.tm_isdst = 0; - return timegm(&timeinfo); + return mktime(&timeinfo); } -void sync_to_rx_rtc(int32_t offset) { - if(!rx_rtc_avail) return; - RX8010SJ::DateTime rx_currenttime = RX8010SJ::DateTime(); - timeToDateTime(rtc.getEpoch() + offset, &rx_currenttime); - rx_rtc.writeDateTime(rx_currenttime); -} void sync_from_rx_rtc(int32_t offset) { if(!rx_rtc_avail) return; RX8010SJ::DateTime dateTime = rx_rtc.readDateTime(); rtc.setTime(dateTimeToTime(&dateTime) + offset); +} + +void set_time(time_t time) { + rtc.setTime(time); + if(!rx_rtc_avail) return; + RX8010SJ::DateTime rx_currenttime = RX8010SJ::DateTime(); + timeToDateTime(time, &rx_currenttime); + rx_rtc.writeDateTime(rx_currenttime); } \ No newline at end of file