#ifndef SYSTEM_H
#define SYSTEM_H
#include "CH32V00xxx.h"
struct NVIC_Type {
    __I  uint32_t ISR[8];
    __I  uint32_t IPR[8];
    __IO uint32_t ITHRESDR;
    __IO uint32_t RESERVED;
    __IO uint32_t CFGR;
    __I  uint32_t GISR;
    __IO uint8_t VTFIDR[4];
    uint8_t RESERVED0[12];
    __IO uint32_t VTFADDR[4];
    uint8_t RESERVED1[0x90];
    __O  uint32_t IENR[8];
    uint8_t RESERVED2[0x60];
    __O  uint32_t IRER[8];
    uint8_t RESERVED3[0x60];
    __O  uint32_t IPSR[8];
    uint8_t RESERVED4[0x60];
    __O  uint32_t IPRR[8];
    uint8_t RESERVED5[0x60];
    __IO uint32_t IACTR[8];
    uint8_t RESERVED6[0xE0];
    __IO uint8_t IPRIOR[256];
    uint8_t RESERVED7[0x810];
    __IO uint32_t SCTLR;
    void EnableIRQ (IRQn IRQ) {
      IENR [((uint32_t)(IRQ) >> 5)] = (1 << ((uint32_t)(IRQ) & 0x1F));
    }
    void DisableIRQ (IRQn IRQ) {
      IRER [((uint32_t)(IRQ) >> 5)] = (1 << ((uint32_t)(IRQ) & 0x1F));
    }
};
NVIC_Type & NVIC = * reinterpret_cast<NVIC_Type * const> (0xE000E000);
struct SysTick_Type {
  union CTLR_DEF  {
    struct {
      __IO ONE_BIT    STE     :  1; //!<[00] System counter enable
      __IO ONE_BIT    STIE    :  1; //!<[01] System counter interrupt enable
      __IO ONE_BIT    STCLK   :  1; //!<[02] System selects the clock source
      __IO ONE_BIT    STRE    :  1; //!<[03] System reload register
           uint32_t   UNUSED0 : 27; //!<[06] 
      __IO ONE_BIT    SWIE    :  1; //!<[31] System software triggered interrupts enable
    } B;
    __IO uint32_t  R;
    template<typename F> void modify (F f) volatile {
      CTLR_DEF r; r.R = R;
      R = f (r);
    }
  };
    __IO CTLR_DEF CTLR;
    __IO uint32_t SR;
    __IO uint32_t CNT;
    uint32_t RESERVED0;
    __IO uint32_t CMP;
    uint32_t RESERVED1;
    void Config (const uint32_t ticks) {
      CNT = 0u;
      CMP = ticks - 1u;
      CTLR.modify ([] (CTLR_DEF & r) -> auto {
        r.B.STE   = SET;
        r.B.STIE  = SET;
        r.B.STCLK = SET;
        r.B.STRE  = SET;        
        return r.R;
      });
      NVIC.EnableIRQ (SysTicK_IRQn);
    }
};
SysTick_Type & SysTick = * reinterpret_cast<SysTick_Type * const> (0xE000F000);

#endif // SYSTEM_H