Exemplo n.º 1
0
 public TimerService(IConfigProvider configProvider, IDateTimeWrapper dateTimeWrapper, ILogger <TimerService> logger, ITariffService tariffService)
 {
     _config          = configProvider.Get <TimerConfig>();
     _dateTimeWrapper = dateTimeWrapper;
     _logger          = logger;
     _tariffService   = tariffService;
 }
Exemplo n.º 2
0
        protected override void OnCreate()
        {
            TimerConfig config = TimerConfig.Default();

            config.Top       = 685;
            config.Left      = 772;
            config.Color     = "red";
            config.Font_Size = 20;
            SetTimerConfig(config);
            if (ConfigFile.ReadConfigAndCreate("AppData", "AutoRun", "1").Trim() == "1")
            {
                if (SetAutoRunCtrlRegInfo(true))
                {
                    Log.Info("设置开机自启动成功");
                }
            }
            //初装机注册文件
            if (GlobalAppData.GetInstance().AppFirst&& RegsvrStarTrans())
            {
                Log.Info("注册成功");
                GlobalAppData.GetInstance().AppFirst = false;
            }

            ReceiptPrinter.AddedToManager();
        }
Exemplo n.º 3
0
 public Timer(IOptions <TimerConfig> config,
              IBackgroundTaskQueue <MotorCloudEvent <IJobExecutionContext> > queue,
              IApplicationNameService applicationNameService)
 {
     _queue = queue;
     _applicationNameService = applicationNameService;
     _config = config?.Value ?? throw new ArgumentNullException(nameof(config.Value));
 }
Exemplo n.º 4
0
        private void OnTimerFired(object timerConfig)
        {
            lock (_inTimerCallbackLock)
            {
                T callbackParam;
                if (_queue.TryDequeue(out callbackParam))
                {
                    TimerConfig <T> config = (TimerConfig <T>)timerConfig;

                    try
                    {
                        _callbacksInFlight++;

                        bool      runComplete     = false;
                        Exception loggedException = null;
                        try
                        {
                            config.Callback(callbackParam);
                            runComplete = true;
                        }
                        catch (Exception ex)
                        {
                            LogManager.Log.Error("Error in Throttled Processor Action", ex);
                            loggedException = ex;
                        }

                        try
                        {
                            if (runComplete)
                            {
                                if (config.SuccessCallback != null)
                                {
                                    config.SuccessCallback(callbackParam);
                                }
                            }
                            else
                            {
                                if (config.FailedCallback != null)
                                {
                                    config.FailedCallback(callbackParam, loggedException);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogManager.Log.Error("Error in Throttled Processor Reporting Callback", ex);
                        }
                    }
                    finally
                    {
                        _callbacksInFlight--;
                    }
                }
            }
        }
Exemplo n.º 5
0
        public ThrottledProcessor(int msBetween, Action <T> callback, Action <T> successCallback, ThrottledProcessorFailedCallback <T> failedCallback)
        {
            _queue = new ConcurrentQueue <T>();

            TimerConfig <T> config = new TimerConfig <T>
            {
                Callback        = callback,
                SuccessCallback = successCallback,
                FailedCallback  = failedCallback,
            };

            _timer = new Timer(OnTimerFired, config, 0, msBetween);
        }
Exemplo n.º 6
0
        protected override void OnCreate()
        {
            var config = TimerConfig.Default();

            config.Left      = 868;
            config.Top       = 64;
            config.Font_Size = 22;
            SetTimerConfig(config);

            //if (ConfigFile.ReadConfigAndCreate("AppData", "AutoRun", "1").Trim() == "1")
            //{
            //    if (SetAutoRunCtrlRegInfo(true))
            //        Log.Info("设置开机自启动成功");
            //}

            #region 此功能在配置参数时已实现
            //if (ConfigFile.ReadConfigAndCreate("AppData", "AutoRun", "1").Trim() == "1")
            //{
            //    if (SetAutoRunCtrlRegInfo(true))
            //        Log.Info("设置开机自启动成功");
            //}
            //else
            //{
            //    if (SetAutoRunCtrlRegInfo(false))
            //        Log.Info("取消开机自启动成功");
            //}
            #endregion

            //初装机注册文件
            if (GlobalAppData.GetInstance().AppFirst&& RegsvrStarTrans())
            {
                Log.Info("注册成功");
                GlobalAppData.GetInstance().AppFirst = false;
            }

            //GPRS.AddedToManager();
            CardReader.AddedToManager();
            Esam.AddedToManager();
            ReceiptPrinter.AddedToManager();
            //R80.AddedToManager();
            GasCardReader.AddedToManager();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Draws the background pie
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnDrawBackCircle(PaintEventArgs e, TimerConfig timer, Func <Color, Brush>[] createBrush, bool createLastCountdownEffects)
        {
            /*
             * Creates a filled pie
             */
            /* local */ void fillPie(Brush color, float startAngle, float angle, float scale, float centerOffset)
            {
                Rectangle area = new Rectangle(
                    x: squareArea.X + (int)(squareArea.Width * (1 - scale) / 2f),
                    y: squareArea.Y + (int)(squareArea.Height * (1 - scale) / 2f),
                    width: Math.Max(1, (int)(squareArea.Width * scale)),
                    height: Math.Max(1, (int)(squareArea.Height * scale))
                    );

                Region       region = new Region();
                GraphicsPath path   = new GraphicsPath();

                path.AddPie(area, -90 + startAngle, angle);

                region.MakeEmpty();
                region.Union(path);

                if (centerOffset > 0)
                {
                    GraphicsPath exclPath = new GraphicsPath();
                    Rectangle    exclArea = new Rectangle(
                        x: squareArea.X + (int)(squareArea.Width * (1 - centerOffset) / 2f),
                        y: squareArea.Y + (int)(squareArea.Height * (1 - centerOffset) / 2f),
                        width: Math.Max(1, (int)(squareArea.Width * centerOffset)),
                        height: Math.Max(1, (int)(squareArea.Height * centerOffset))
                        );

                    exclPath.AddEllipse(exclArea);
                    region.Exclude(exclPath);
                    exclPath.Dispose();
                }

                e.Graphics.FillRegion(color, region);
                region.Dispose();
                path.Dispose();
            }

            /*
             * Creates an unfilled pie
             */
            /* local */ void drawPie(Pen color, float startAngle, float angle, float scale)
            {
                Rectangle area = new Rectangle(
                    x: squareArea.X + (int)(squareArea.Width * (1 - scale) / 2f),
                    y: squareArea.Y + (int)(squareArea.Height * (1 - scale) / 2f),
                    width: Math.Max(1, (int)(squareArea.Width * scale)),
                    height: Math.Max(1, (int)(squareArea.Height * scale))
                    );

                e.Graphics.DrawPie(color, area, -90 + startAngle, angle);
            }

            //Color scheme to use
            Color[] colors = timer.AnalogColors;

            //Create the final-minute color shift
            if (createLastCountdownEffects && timer.TimeLeft.TotalMinutes < 1f && !timer.Overtime)
            {
                fillPie(
                    color: BG_BRUSH,
                    startAngle: (DateTime.Now.Second + DateTime.Now.Millisecond / 1000f) / 60f * 360f,
                    angle: (float)timer.RealTimeLeft.TotalSeconds / 60f * 360f,
                    scale: 1 - BG_FRAME_SCALE,
                    centerOffset: 0f
                    );
            }

            /*
             * Draw pies
             */

            //Draw for days (more than 1 day)
            if (timer.TimeLeft.TotalDays >= 1)
            {
                float dividend = 1f;
                for (int i = 0; i < Math.Ceiling(timer.TimeLeft.TotalDays / 12); i++)
                {
                    //Create a colored pen based on what days we are drawing
                    using (Brush b = createBrush[i % createBrush.Length](colors[(i + 6) % colors.Length]))
                    {
                        if (i == Math.Floor(timer.TimeLeft.TotalDays / 12))
                        {
                            fillPie(
                                color: b,
                                startAngle: 0f,
                                angle: (float)timer.TimeLeft.TotalDays % 12f * 360f / 12f,
                                scale: DISC_INITAL_SCALE / dividend,
                                centerOffset: DISC_INITAL_SCALE_HOURS
                                );
                        }
                        else
                        {
                            fillPie(
                                color: b,
                                startAngle: 0f,
                                angle: 360f,
                                scale: DISC_INITAL_SCALE / dividend,
                                centerOffset: DISC_INITAL_SCALE_HOURS
                                );
                        }
                    }

                    dividend += DISC_INITAL_SCALE_HOURS;
                }

                //Draw lines segmenting the bar
                using (Pen p = new Pen(Color.FromArgb(0x7F, Color.Silver), 1.5f)
                {
                    DashStyle = DashStyle.Dash
                })
                {
                    for (int a = 0; a < Math.Min(12, timer.TimeLeft.TotalDays); a++)
                    {
                        Point  center     = new Point(squareArea.X + squareArea.Width / 2, squareArea.Y + squareArea.Height / 2);
                        PointF startPoint = GetPointAtAngle(center, (int)(DISC_INITAL_SCALE_HOURS * squareArea.Width / 2), CalculateAngle(a * (timer.Overtime ? -1 : 1), 12));
                        PointF endPoint   = GetPointAtAngle(center, (int)(DISC_INITAL_SCALE * squareArea.Width / 2), CalculateAngle(a * (timer.Overtime ? -1 : 1), 12));

                        e.Graphics.DrawLine(p, startPoint, endPoint);
                    }
                }

                //Draw week indicators
                fillPie(Brushes.Gray, 7 / 12f * 360f, 1f, DISC_INITAL_SCALE, DISC_INITAL_SCALE_HOURS);

                if (timer.TimeLeft.TotalDays >= 7f)
                {
                    fillPie(Brushes.Gray, 2 / 12f * 360f, 1f, DISC_INITAL_SCALE, DISC_INITAL_SCALE_HOURS);
                }

                if (timer.TimeLeft.TotalDays >= 14f)
                {
                    fillPie(Brushes.Gray, 9 / 12f * 360f, 1f, DISC_INITAL_SCALE, DISC_INITAL_SCALE_HOURS);
                }

                //fillPie(BG_BRUSH, 0f, 360f, DISC_INITAL_SCALE_HOURS);
            }

            //Draw for hours (more than 3 hours)
            else if (timer.TimeLeft.TotalHours >= 3)
            {
                float dividend = 1f;
                for (int i = 0; i < Math.Ceiling(timer.TimeLeft.TotalDays * 2); i++)
                {
                    //Create a colored pen based on what hours we are drawing
                    using (Brush b = createBrush[i % createBrush.Length](colors[(i + 4) % colors.Length]))
                    {
                        if (i == Math.Floor(timer.TimeLeft.TotalDays * 2))
                        {
                            fillPie(
                                color: b,
                                startAngle: ((DateTime.Now.Hour % 12) + DateTime.Now.Minute / 60f) / 12f * 360f,
                                angle: (float)(timer.RealTimeLeft.TotalHours % 12) / 12f * 360f,
                                scale: DISC_INITAL_SCALE_HOURS / dividend,
                                centerOffset: 0f
                                );
                        }
                        else
                        {
                            fillPie(
                                color: b,
                                startAngle: 0f,
                                angle: 360f,
                                scale: DISC_INITAL_SCALE_HOURS / dividend,
                                centerOffset: 0f
                                );
                        }
                    }

                    dividend += DISC_INITAL_SCALE_HOURS;
                }
            }

            //Draw for minutes (less than 3 hours)
            else
            {
                float dividend = 1f;
                for (int i = 0; i < Math.Ceiling(timer.TimeLeft.TotalHours); i++)
                {
                    //Create a colored pen based on what hour we are drawing
                    using (Brush b = createBrush[i % createBrush.Length](colors[i % colors.Length]))
                    {
                        if (i == Math.Floor(timer.TimeLeft.TotalHours))
                        {
                            fillPie(
                                color: b,
                                startAngle: (DateTime.Now.Minute + DateTime.Now.Second / 60f) / 60f * 360f,
                                angle: (float)(timer.RealTimeLeft.TotalMinutes % 60) / 60f * 360f,
                                scale: DISC_INITAL_SCALE / dividend,
                                centerOffset: 0f
                                );
                        }
                        else
                        {
                            fillPie(
                                color: b,
                                startAngle: 0f,
                                angle: 360f,
                                scale: DISC_INITAL_SCALE / dividend,
                                centerOffset: 0f
                                );
                        }
                    }

                    dividend += DISC_DIVIDEND_INCREMENT;
                }
            }

            //Draw for seconds (less than 12 minutes)
            if (createLastCountdownEffects && timer.TimeLeft.TotalMinutes < 12 && !(timer.Overtime && timer.StopAtZero))
            {
                using (Pen p = new Pen(colors[10 % colors.Length], 2f)
                {
                    DashStyle = DashStyle.Dash
                })
                {
                    drawPie(
                        color: p,
                        startAngle: 0f,
                        angle: (float)timer.RealTimeLeft.TotalMinutes / 12f * 360f,
                        scale: DISC_INITAL_SCALE
                        );
                }
            }
        }
Exemplo n.º 8
0
        public STM32F4_RTC(Machine machine)
        {
            mainTimer = new TimerConfig(this);
            alarmA    = new AlarmConfig(this, mainTimer);
            alarmB    = new AlarmConfig(this, mainTimer);

            AlarmIRQ             = new GPIO();
            ticker               = new LimitTimer(machine.ClockSource, 1, this, nameof(ticker), 1, direction: Direction.Ascending, eventEnabled: true);
            ticker.LimitReached += UpdateState;
            ResetInnerTimers();

            IFlagRegisterField syncFlag = null;

            var registerMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.TimeRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 4, name: "SU",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.TimeRegister, DateTimeSelect.Second, Rank.Units, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Second, Rank.Units))
                  .WithValueField(4, 3, name: "ST",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.TimeRegister, DateTimeSelect.Second, Rank.Tens, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Second, Rank.Tens))
                  .WithReservedBits(7, 1)
                  .WithValueField(8, 4, name: "MU",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.TimeRegister, DateTimeSelect.Minute, Rank.Units, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Minute, Rank.Units))
                  .WithValueField(12, 3, name: "MT",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.TimeRegister, DateTimeSelect.Minute, Rank.Tens, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Minute, Rank.Tens))
                  .WithReservedBits(15, 1)
                  .WithValueField(16, 4, name: "HU",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.TimeRegister, DateTimeSelect.Hour, Rank.Units, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Hour, Rank.Units))
                  .WithValueField(20, 2, name: "HT",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.TimeRegister, DateTimeSelect.Hour, Rank.Tens, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Hour, Rank.Tens))
                  .WithFlag(22, name: "PM",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfInInitMode(Registers.TimeRegister) && CheckIfUnlocked(Registers.TimeRegister))
                        {
                            mainTimer.PM = value;
                        }
                    },
                            valueProviderCallback: _ => mainTimer.PM)
                  .WithReservedBits(23, 9) },
                { (long)Registers.DateRegister, new DoubleWordRegister(this, 0x2101)
                  .WithValueField(0, 4, name: "DU",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.DateRegister, DateTimeSelect.Day, Rank.Units, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Day, Rank.Units))
                  .WithValueField(4, 2, name: "DT",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.DateRegister, DateTimeSelect.Day, Rank.Tens, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Day, Rank.Tens))
                  .WithReservedBits(6, 2)
                  .WithValueField(8, 4, name: "MU",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.DateRegister, DateTimeSelect.Month, Rank.Units, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Month, Rank.Units))
                  .WithValueField(12, 1, name: "MT",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.DateRegister, DateTimeSelect.Month, Rank.Tens, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Month, Rank.Tens))
                  .WithValueField(13, 3, name: "WDU",
                                  writeCallback: (_, value) =>
                    {
                        if (CheckIfInInitMode(Registers.DateRegister) && CheckIfUnlocked(Registers.DateRegister))
                        {
                            if (value == 0)
                            {
                                this.Log(LogLevel.Warning, "Writting value 0 to WeekDay register is forbidden");
                                return;
                            }
                            mainTimer.WeekDay = (DayOfTheWeek)value;
                        }
                    },
                                  valueProviderCallback: _ => (uint)mainTimer.WeekDay)
                  .WithValueField(16, 4, name: "YU",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.DateRegister, DateTimeSelect.Year, Rank.Units, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Year, Rank.Units))
                  .WithValueField(20, 4, name: "YT",
                                  writeCallback: (_, value) => UpdateMainTimer(Registers.DateRegister, DateTimeSelect.Year, Rank.Tens, value),
                                  valueProviderCallback: _ => mainTimer.Read(DateTimeSelect.Year, Rank.Tens))
                  .WithReservedBits(24, 8) },
                { (long)Registers.ControlRegister, new DoubleWordRegister(this)
                  .WithTag("WUCKSEL", 0, 3)
                  .WithTag("TSEDGE", 3, 1)
                  .WithTag("REFCKON", 4, 1)
                  .WithTag("BYPSHAD", 5, 1)
                  .WithFlag(6, name: "FMT",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfUnlocked(Registers.ControlRegister))
                        {
                            AMPMFormat = value;

                            mainTimer.ConfigureAMPM();
                            alarmA.ConfigureAMPM();
                            alarmB.ConfigureAMPM();
                        }
                    },
                            valueProviderCallback: _ => AMPMFormat)
                  .WithTag("DCE", 7, 1)
                  .WithFlag(8, name: "ALRAE",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfUnlocked(Registers.ControlRegister))
                        {
                            alarmA.Enable = value;
                        }
                    },
                            valueProviderCallback: _ => alarmA.Enable)
                  .WithFlag(9, name: "ALRBE",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfUnlocked(Registers.ControlRegister))
                        {
                            alarmB.Enable = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.Enable)
                  .WithTag("WUTE", 10, 1)  // Wakeup Timer not supported
                  .WithTag("TSE", 11, 1)   // Timestamp not supported
                  .WithFlag(12, name: "ALRAIE",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfUnlocked(Registers.ControlRegister))
                        {
                            alarmA.InterruptEnable = value;
                        }
                    },
                            valueProviderCallback: _ => alarmA.InterruptEnable)
                  .WithFlag(13, name: "ALRBIE",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfUnlocked(Registers.ControlRegister) && value)
                        {
                            alarmB.InterruptEnable = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.InterruptEnable)
                  .WithTag("WUTIE", 14, 1)  // Wakeup Timer not supported
                  .WithTag("TSIE", 15, 1)   // Timestamp not supported
                  .WithTag("ADD1H", 16, 1)
                  .WithTag("SUB1H", 17, 1)
                  .WithTag("BKP", 18, 1)
                  .WithTag("COSEL", 19, 1)
                  .WithTag("POL", 20, 1)
                  .WithTag("OSEL", 21, 2)
                  .WithTag("COE", 23, 1)
                  .WithReservedBits(24, 8) },
                { (long)Registers.ISR, new DoubleWordRegister(this, 0x7)
                  .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => !alarmA.Enable, name: "ALRAWF")
                  .WithFlag(1, FieldMode.Read, valueProviderCallback: _ => !alarmB.Enable, name: "ALRBWF")
                  .WithTag("WUTWF", 2, 1)
                  .WithTag("SHPF", 3, 1)
                  .WithFlag(4, FieldMode.Read, valueProviderCallback: _ => mainTimer.TimeState.Year != 2000, name: "INITS")
                  .WithFlag(5, out syncFlag, FieldMode.Read | FieldMode.WriteZeroToClear, name: "RSF",
                            readCallback: (_, curr) =>
                    {
                        // this strange logic is required by the Zephyr driver;
                        // it wants to read 0 before reading 1, otherwise it times-out
                        if (!curr)
                        {
                            syncFlag.Value = true;
                        }
                    })
                  .WithFlag(6, FieldMode.Read, valueProviderCallback: _ => initMode, name: "INITF")
                  .WithFlag(7, FieldMode.Write, name: "INIT",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfUnlocked(Registers.ISR))
                        {
                            ticker.Enabled = !value;
                            initMode       = value;
                        }
                    })
                  .WithFlag(8, FieldMode.WriteZeroToClear | FieldMode.Read, name: "ALRAF",
                            changeCallback: (_, __) =>
                    {
                        alarmA.Flag = false;
                    },
                            valueProviderCallback: _ => alarmA.Flag)
                  .WithFlag(9, FieldMode.WriteZeroToClear | FieldMode.Read, name: "ALRBF",
                            changeCallback: (_, __) =>
                    {
                        alarmB.Flag = false;
                    },
                            valueProviderCallback: _ => alarmB.Flag)
                  .WithTag("WUTF", 10, 1)
                  .WithTag("TSF", 11, 1)
                  .WithTag("TSOVF", 12, 1)
                  .WithTag("TAMP1F", 13, 1)
                  .WithTag("TAMP2F", 14, 1)
                  .WithReservedBits(15, 1)
                  .WithTag("RECALPF", 16, 1)
                  .WithReservedBits(17, 15) },
                { (long)Registers.PrescalerRegister, new DoubleWordRegister(this)
                  .WithTag("PREDIV_S", 0, 15)
                  .WithReservedBits(15, 1)
                  .WithTag("PREDIV_A", 16, 7)
                  .WithReservedBits(23, 9) },
                { (long)Registers.WakeupTimerRegister, new DoubleWordRegister(this, 0x7F00FF)
                  .WithTag("WUT", 0, 16)
                  .WithReservedBits(16, 16) },
                { (long)Registers.CalibrationRegister, new DoubleWordRegister(this)
                  .WithTag("DC", 0, 5)
                  .WithReservedBits(5, 2)
                  .WithTag("DCS", 7, 1)
                  .WithReservedBits(8, 24) },
                { (long)Registers.AlarmARegister, new DoubleWordRegister(this)
                  .WithValueField(0, 4, name: "SU",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Second, Rank.Units, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Second, Rank.Units))
                  .WithValueField(4, 3, name: "ST",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Second, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Second, Rank.Tens))
                  .WithFlag(7, name: "MSK1",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmA) && CheckIfUnlocked(Registers.AlarmARegister))
                        {
                            alarmA.SecondsMask = value;
                        }
                    },
                            valueProviderCallback: _ => alarmA.SecondsMask)
                  .WithValueField(8, 4, name: "MU",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Minute, Rank.Units, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Minute, Rank.Units))
                  .WithValueField(12, 3, name: "MT",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Minute, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Minute, Rank.Tens))
                  .WithFlag(15, name: "MSK2",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmA) && CheckIfUnlocked(Registers.AlarmARegister))
                        {
                            alarmA.MinutesMask = value;
                        }
                    }, valueProviderCallback: _ => alarmA.MinutesMask)
                  .WithValueField(16, 4, name: "HU",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Hour, Rank.Units, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Hour, Rank.Units))
                  .WithValueField(20, 2, name: "HT",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Hour, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Hour, Rank.Tens))
                  .WithFlag(22, name: "PM",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmA) && CheckIfUnlocked(Registers.AlarmARegister))
                        {
                            alarmA.PM = value;
                        }
                    },
                            valueProviderCallback: _ => alarmA.PM)
                  .WithFlag(23, name: "MSK3",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmA) && CheckIfUnlocked(Registers.AlarmARegister))
                        {
                            alarmA.HoursMask = value;
                        }
                    }, valueProviderCallback: _ => alarmA.HoursMask)
                  .WithValueField(24, 4, name: "DU",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Day, Rank.Units, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Day, Rank.Units))
                  .WithValueField(28, 2, name: "DT",
                                  writeCallback: (_, value) => UpdateTimerA(DateTimeSelect.Day, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmA.Read(DateTimeSelect.Day, Rank.Tens))
                  .WithTag("WDSEL", 30, 1)   // Weekday instead of date units usupported
                  .WithFlag(31, name: "MSK4",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmA) && CheckIfUnlocked(Registers.AlarmARegister))
                        {
                            alarmA.DaysMask = value;
                        }
                    },
                            valueProviderCallback: _ => alarmA.DaysMask) },
                { (long)Registers.AlarmBRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 4, name: "SU",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Second, Rank.Units, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Second, Rank.Units))
                  .WithValueField(4, 3, name: "ST",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Second, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Second, Rank.Tens))
                  .WithFlag(7, name: "MSK1",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmB) && CheckIfUnlocked(Registers.AlarmBRegister))
                        {
                            alarmB.SecondsMask = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.SecondsMask)
                  .WithValueField(8, 4, name: "MU",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Minute, Rank.Units, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Minute, Rank.Units))
                  .WithValueField(12, 3, name: "MT",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Minute, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Minute, Rank.Tens))
                  .WithFlag(15, name: "MSK2",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmB) && CheckIfUnlocked(Registers.AlarmBRegister))
                        {
                            alarmB.MinutesMask = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.MinutesMask)
                  .WithValueField(16, 4, name: "HU",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Hour, Rank.Units, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Hour, Rank.Units))
                  .WithValueField(20, 2, name: "HT",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Hour, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Hour, Rank.Tens))
                  .WithFlag(22, name: "PM",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmB) && CheckIfUnlocked(Registers.AlarmBRegister))
                        {
                            alarmB.PM = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.PM)
                  .WithFlag(23, name: "MSK3",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmB) && CheckIfUnlocked(Registers.AlarmBRegister))
                        {
                            alarmB.HoursMask = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.HoursMask)
                  .WithValueField(24, 4, name: "DU",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Day, Rank.Units, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Day, Rank.Units))
                  .WithValueField(28, 2, name: "DT",
                                  writeCallback: (_, value) => UpdateTimerB(DateTimeSelect.Day, Rank.Tens, value),
                                  valueProviderCallback: _ => alarmB.Read(DateTimeSelect.Day, Rank.Tens))
                  .WithTag("WDSEL", 30, 1)   // Weekday instead of date units usupported
                  .WithFlag(31, name: "MSK4",
                            writeCallback: (_, value) =>
                    {
                        if (CheckIfDisabled(alarmB) && CheckIfUnlocked(Registers.AlarmBRegister))
                        {
                            alarmB.DaysMask = value;
                        }
                    },
                            valueProviderCallback: _ => alarmB.DaysMask) },
                { (long)Registers.WriteProtectionRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 8, name: "KEY",
                                  writeCallback: (_, value) =>
                    {
                        if (value == UnlockKey1 && !firstStageUnlocked)
                        {
                            firstStageUnlocked = true;
                        }
                        else if (value == UnlockKey2 && firstStageUnlocked)
                        {
                            registersUnlocked = true;
                        }
                        else
                        {
                            firstStageUnlocked = false;
                            registersUnlocked  = false;
                        }
                    },
                                  valueProviderCallback: _ => 0)
                  .WithReservedBits(8, 24) },
                { (long)Registers.SubSecondRegister, new DoubleWordRegister(this)
                  .WithTag("SS", 0, 16)
                  .WithReservedBits(16, 16) },
                { (long)Registers.ShiftControlRegister, new DoubleWordRegister(this)
                  .WithTag("SUBFS", 0, 15)
                  .WithReservedBits(15, 16)
                  .WithTag("ADD1S", 31, 1) },
                { (long)Registers.TimestampTimeRegister, new DoubleWordRegister(this)
                  .WithTag("Second", 0, 7)
                  .WithReservedBits(7, 1)
                  .WithTag("Minute", 8, 7)
                  .WithReservedBits(15, 1)
                  .WithTag("Hour", 16, 6)
                  .WithTag("PM", 22, 1)
                  .WithReservedBits(23, 9) },
                { (long)Registers.TimestampDateRegister, new DoubleWordRegister(this)
                  .WithTag("Day", 0, 6)
                  .WithReservedBits(6, 2)
                  .WithTag("Month", 8, 5)
                  .WithTag("WDU", 13, 3)
                  .WithReservedBits(16, 16) },
                { (long)Registers.TimestampSubSecondRegister, new DoubleWordRegister(this)
                  .WithTag("SS", 0, 16)
                  .WithReservedBits(16, 16) },
                { (long)Registers.ClockCalibrationRegister, new DoubleWordRegister(this)
                  .WithTag("CALM", 0, 9)
                  .WithReservedBits(9, 4)
                  .WithTag("CALW16", 13, 1)
                  .WithTag("CALW8", 14, 1)
                  .WithTag("CALP", 15, 1)
                  .WithReservedBits(16, 16) },
                { (long)Registers.TamperAndAlternateFunctionConfigurationRegister, new DoubleWordRegister(this)
                  .WithTag("TAMP1E", 0, 1)
                  .WithTag("TAMP1TRG", 1, 1)
                  .WithTag("TAMPIE", 2, 1)
                  .WithTag("TAMP2E", 3, 1)
                  .WithTag("TAMP2TRG", 4, 1)
                  .WithReservedBits(5, 2)
                  .WithTag("TAMPTS", 7, 1)
                  .WithTag("TAMPFREQ", 8, 3)
                  .WithTag("TAMPFLT", 11, 2)
                  .WithTag("TAMPPRCH", 13, 2)
                  .WithTag("TAMPPUDIS", 15, 1)
                  .WithTag("TAMP1INSEL", 16, 1)
                  .WithTag("TSINSEL", 17, 1)
                  .WithTag("ALARMOUTTYPE", 18, 1)
                  .WithReservedBits(19, 13) },
                { (long)Registers.AlarmASubSecondRegister, new DoubleWordRegister(this)
                  .WithTag("SS", 0, 15)
                  .WithReservedBits(15, 9)
                  .WithTag("MASKSS", 24, 4)
                  .WithReservedBits(28, 4) },
                { (long)Registers.AlarmBSubSecondRegister, new DoubleWordRegister(this)
                  .WithTag("SS", 0, 15)
                  .WithReservedBits(15, 9)
                  .WithTag("MASKSS", 24, 4)
                  .WithReservedBits(28, 4) },
            };

            registers = new DoubleWordRegisterCollection(this, registerMap);
        }