Skip to content

Commit

Permalink
Update LLD driver for I2C, OTG and ERTC
Browse files Browse the repository at this point in the history
  • Loading branch information
HorrorTroll committed Jul 28, 2024
1 parent fbdaa46 commit 7c973fe
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 64 deletions.
26 changes: 19 additions & 7 deletions os/hal/ports/AT32/LLD/I2Cv1/driver.mk
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
ifeq ($(USE_SMART_BUILD),yes)
ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv1/hal_i2c_lld.c
endif
ifeq ($(USE_HAL_I2C_FALLBACK),yes)
# Fallback SW driver.
ifeq ($(USE_SMART_BUILD),yes)
ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
endif
else
PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
endif
PLATFORMINC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C
else
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv1/hal_i2c_lld.c
endif
ifeq ($(USE_SMART_BUILD),yes)
ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv1/hal_i2c_lld.c
endif
else
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv1/hal_i2c_lld.c
endif

PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv1
PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv1
endif
22 changes: 22 additions & 0 deletions os/hal/ports/AT32/LLD/I2Cv1/hal_i2c_lld.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,16 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
/* Clear ADDR7F flag. */
if (event & (I2C_STS1_ADDR7F | I2C_STS1_ADDRHF))
(void)dp->STS2;
/* BUSERR flag doesnt happen anymore in event handling */
#if 0
/* Errata 1.14.2 for AT32F415, I2C communication error when BUSERR is detected on bus.*/
/* Errata 1.4.4 for AT32F403A/7, BUSERR is detected by I2C before start of communication.*/
/* Errata 1.15.2 for AT32F413, BUSERR is detected by I2C before start of communication.*/
/* Errata 1.2.2 for AT32A403A, BUSERR is detected by I2C before start of communication.*/
if (event & I2C_STS1_BUSERR) {
dp->STS1 &= ~I2C_STS1_BUSERR;
}
#endif
}

/**
Expand Down Expand Up @@ -354,6 +364,18 @@ static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sts) {

if (sts & I2C_STS1_BUSERR) { /* Bus error. */
i2cp->errors |= I2C_BUS_ERROR;
/* No more needed */
#if 0
/* Errata 1.14.2 for AT32F415, I2C communication error when BUSERR is
detected on bus.*/
/* Errata 1.4.4 for AT32F403A/7, BUSERR is detected by I2C before start
of communication.*/
/* Errata 1.15.2 for AT32F413, BUSERR is detected by I2C before start
of communication.*/
/* Errata 1.2.2 for AT32A403A, BUSERR is detected by I2C before start
of communication.*/
i2cp->i2c->STS1 &= ~I2C_STS1_BUSERR;
#endif
}

if (sts & I2C_STS1_ARLOST) /* Arbitration lost. */
Expand Down
2 changes: 1 addition & 1 deletion os/hal/ports/AT32/LLD/I2Cv1/hal_i2c_lld.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
#endif

/* Check clock range. */
#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 72)
#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 75)
#error "I2C peripheral clock frequency out of range."
#endif

Expand Down
34 changes: 1 addition & 33 deletions os/hal/ports/AT32/LLD/OTGv1/hal_usb_lld.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,8 @@
#endif

#elif AT32_OTG_STEPPING == 2
#if defined(BOARD_OTG_VBUSIG_LPM)
#define GCCFG_INIT_VALUE (GCCFG_VBUSIG | GCCFG_LP_MODE | \
GCCFG_PWRDOWN)
#elif defined(BOARD_OTG_VBUSIG)
#if defined(BOARD_OTG_VBUSIG)
#define GCCFG_INIT_VALUE (GCCFG_VBUSIG | GCCFG_PWRDOWN)
#elif defined(BOARD_OTG_LPM)
#define GCCFG_INIT_VALUE (GCCFG_LP_MODE | GCCFG_PWRDOWN)
#else
#define GCCFG_INIT_VALUE GCCFG_PWRDOWN
#endif
Expand Down Expand Up @@ -792,16 +787,6 @@ void usb_lld_start(USBDriver *usbp) {
crmEnableOTG_HS(true);
crmResetOTG_HS();

/* ULPI clock is managed depending on the presence of an external
PHY.*/
#if defined(BOARD_OTG2_USES_ULPI)
crmEnableOTG_HSULPI(true);
#else
/* Workaround for the problem described here:
http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798.*/
crmDisableOTG_HSULPI();
#endif

/* Enables IRQ vector.*/
nvicEnableVector(AT32_OTG2_NUMBER, AT32_USB_OTG2_IRQ_PRIORITY);

Expand Down Expand Up @@ -833,21 +818,7 @@ void usb_lld_start(USBDriver *usbp) {
/* PHY enabled.*/
otgp->PCGCCTL = 0;

#if defined(BOARD_OTG2_USES_ULPI)
#if AT32_USB_USE_OTG1
if (&USBD1 == usbp) {
otgp->GCCFG = GCCFG_INIT_VALUE;
}
#endif

#if AT32_USB_USE_OTG2
if (&USBD2 == usbp) {
otgp->GCCFG = 0;
}
#endif
#else
otgp->GCCFG = GCCFG_INIT_VALUE;
#endif

/* Soft core reset.*/
otg_core_reset(usbp);
Expand Down Expand Up @@ -913,9 +884,6 @@ void usb_lld_stop(USBDriver *usbp) {
if (&USBD2 == usbp) {
nvicDisableVector(AT32_OTG2_NUMBER);
crmDisableOTG_HS();
#if defined(BOARD_OTG2_USES_ULPI)
crmDisableOTG_HSULPI();
#endif
}
#endif
}
Expand Down
2 changes: 0 additions & 2 deletions os/hal/ports/AT32/LLD/OTGv1/hal_usb_lld.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,9 @@
#error "unsupported AT32_OTG_STEPPING"
#endif

/*
#if !defined(AT32_HAS_OTG1) || !defined(AT32_HAS_OTG2)
#error "AT32_HAS_OTGx not defined in registry"
#endif
*/

#if AT32_HAS_OTG1 && !defined(AT32_OTG1_ENDPOINTS)
#error "AT32_OTG1_ENDPOINTS not defined in registry"
Expand Down
66 changes: 45 additions & 21 deletions os/hal/ports/AT32/LLD/RTCv2/hal_rtc_lld.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ OSAL_IRQ_HANDLER(AT32_ERTC_COMMON_HANDLER) {
#if defined(ERTC_STS_TP1F)
| ERTC_STS_TP1F
#endif
#if defined(ERTC_STS_TP2F)
| ERTC_STS_TP2F
#endif
#if defined(ERTC_STS_WATF)
| ERTC_STS_WATF
#endif
Expand Down Expand Up @@ -337,6 +340,11 @@ OSAL_IRQ_HANDLER(AT32_ERTC_COMMON_HANDLER) {
if ((sts & ERTC_STS_TP1F) != 0U) {
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1);
}
#endif
#if defined(ERTC_STS_TP2F)
if ((sts & ERTC_STS_TP2F) != 0U) {
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2);
}
#endif
}
#endif /* !defined(ERTC_TAMP_TP1EN) */
Expand Down Expand Up @@ -364,6 +372,9 @@ OSAL_IRQ_HANDLER(AT32_ERTC_TAMP_STAMP_HANDLER) {
| ERTC_STS_TSOF
#if defined(ERTC_STS_TP1F)
| ERTC_STS_TP1F
#endif
#if defined(ERTC_STS_TP2F)
| ERTC_STS_TP2F
#endif
);

Expand Down Expand Up @@ -392,6 +403,11 @@ OSAL_IRQ_HANDLER(AT32_ERTC_TAMP_STAMP_HANDLER) {
if ((sts & ERTC_STS_TP1F) != 0U) {
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1);
}
#endif
#if defined(ERTC_STS_TP2F)
if ((sts & ERTC_STS_TP2F) != 0U) {
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2);
}
#endif
}
#endif /* !defined(ERTC_TAMP_TP1EN) */
Expand Down Expand Up @@ -467,7 +483,7 @@ OSAL_IRQ_HANDLER(AT32_ERTC_ALARM_HANDLER) {
}

#else
#error "missing required RTC handlers definitions in IRQ"
#error "missing required RTC handlers definitions in registry"
#endif

/*===========================================================================*/
Expand All @@ -488,21 +504,21 @@ void rtc_lld_init(void) {
RTCD1.rtc = ERTC;

/* Disable write protection. */
RTCD1.rtc->WP = 0xCA;
RTCD1.rtc->WP = 0x53;
RTCD1.rtc->WP = 0xCAU;
RTCD1.rtc->WP = 0x53U;

/* If calendar has not been initialized yet then proceed with the
initial setup.*/
if (!(RTCD1.rtc->STS & ERTC_STS_INITF)) {

rtc_enter_init();

RTCD1.rtc->CTRL = AT32_ERTC_CTRL_INIT;
RTCD1.rtc->CTRL = AT32_ERTC_CTRL_INIT | ERTC_CTRL_DREN;
#if defined(ERTC_TAMP_TP1EN)
RTCD1.rtc->TAMP = AT32_ERTC_TAMP_INIT;
#endif
RTCD1.rtc->STS = ERTC_STS_IMEN; /* Clearing all but ERTC_STS_IMEN. */
RTCD1.rtc->DIV = AT32_ERTC_DIV_BITS;
RTCD1.rtc->DIV = AT32_ERTC_DIV_BITS & 0x7FFFU;
RTCD1.rtc->DIV = AT32_ERTC_DIV_BITS;

rtc_exit_init();
Expand Down Expand Up @@ -567,34 +583,42 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) {
* @notapi
*/
void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
uint32_t date, time, ctrl;
uint32_t ctrl, date, time, prev_date, prev_time;
uint32_t subs;
#if AT32_ERTC_HAS_SUBSECONDS
uint32_t oldsbs, sbs;
uint32_t sbs, prev_sbs;
#endif /* AT32_ERTC_HAS_SUBSECONDS */
syssts_t sts;

/* Entering a reentrant critical zone.*/
sts = osalSysGetStatusAndLockX();

/* Synchronization with the RTC and reading the registers, note
DATE must be read last.*/
while ((rtcp->rtc->STS & ERTC_STS_UPDF) == 0)
;
/* Repeated registers read until 2 matching sets are found.*/
#if AT32_ERTC_HAS_SUBSECONDS
do
#endif /* AT32_ERTC_HAS_SUBSECONDS */
{
oldsbs = rtcp->rtc->SBS;
sbs = 0U;
time = 0U;
date = 0U;
do {
prev_sbs = sbs;
prev_time = time;
prev_date = date;
sbs = rtcp->rtc->SBS;
time = rtcp->rtc->TIME;
date = rtcp->rtc->DATE;
}
#if AT32_ERTC_HAS_SUBSECONDS
while (oldsbs != (sbs = rtcp->rtc->SBS));
(void) rtcp->rtc->DATE;
#endif /* AT32_ERTC_HAS_SUBSECONDS */
} while ((sbs != prev_sbs) || (time != prev_time) || (date != prev_date));
#else /* !AT32_ERTC_HAS_SUBSECONDS */
time = 0U;
date = 0U;
do {
prev_time = time;
prev_date = date;
time = rtcp->rtc->TIME;
date = rtcp->rtc->DATE;
} while ((time != prev_time) || (date != prev_date));
#endif /* !AT32_ERTC_HAS_SUBSECONDS */

/* DST bit is in CTRL, no need to poll on this one.*/
ctrl = rtcp->rtc->CTRL;
rtcp->rtc->STS &= ~ERTC_STS_UPDF;

/* Leaving a reentrant critical zone.*/
osalSysRestoreStatusX(sts);
Expand Down

0 comments on commit 7c973fe

Please sign in to comment.