#include #include volatile uint64_t sys_time_us; uint32_t read_fuse_monitor(void); void set_rj45_leds(uint32_t leds); void set_status_leds(uint32_t leds); int main(void) { /* Configure clocks for 168 MHz system clock. * * HSE @ 8 MHz --[PLL x16 /2]--> PLL "R" clock @ 64 MHz */ /* Enable peripherals */ RCC->APBENR1 |= RCC_APBENR1_PWREN; /* Enable High-speed external crystal oscillator. The board has an 8 MHz crystal. */ RCC->CR |= RCC_CR_HSEON; while (!(RCC->CR & RCC_CR_HSERDY)) { /* wait for HSE osc to stabilize. */ } /* Increase flash wait states to 5 required for operation above 136 MHz */ FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | (2<ACR & FLASH_ACR_LATENCY_Msk) != (2<PLLCFGR = (16<CR |= RCC_CR_PLLON; while (!(RCC->CR & RCC_CR_PLLRDY)) { /* wait for PLL to stabilize. */ } /* Switch SYSCLK to PLL source. */ RCC->CFGR |= (2<CFGR & RCC_CFGR_SWS_Msk) != (2<AHBENR |= RCC_AHBENR_DMA1EN; RCC->APBENR1 |= RCC_APBENR1_USART3EN | RCC_APBENR1_I2C1EN; RCC->APBENR2 |= RCC_APBENR2_USART1EN | RCC_APBENR2_TIM1EN; RCC->IOPENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN | RCC_IOPENR_GPIODEN; /* GPIOA: * A0: MON_H * A1: MON_FAULT_CURRENT * A2: MON_L * A3: (testpoint) * A4: VIN_MON * A5: (testpoint) * A6: RJ45 LED 2 * A7: Pulse RX * A8: Fuse monitor 6 * A9: RS485 TX * A10: RS485 RX * A11: Fuse monitor 1 * A12: RS485 DE * A13: SWDIO * A14: SWCLK * A15: Fuse monitor 4 */ GPIOA->MODER = ANALOG(0) | ANALOG(1) | ANALOG(2) | ANALOG(4) | IN(3) | IN(5) | OUT(6) | ANALOG(7) | IN(8) | IN(11) | IN(15) | AF(9) | AF(10) | AF(12) | AF(13) | AF(14); GPIOA->AFR[1] = AFRH(9, 1) | AFRH(10, 1) | AFRH(12, 1) | AFRH(13, 0) | AFRH(14, 0); GPIOA->OSPEEDR = (3<<(2*9)) | (3<<(2*12)) | (3<<(2*13)); /* GPIOB: * B0: Driver A low (TIM1_CH2N) * B1: Driver B low (TIM1_CH3N) * B2: RJ45 LED 1 * B3: Driver A high (TIM1_CH2) * B4: V_ISO_SENSE * B5: (testpoint) * B6: SCL * B7: SDA * B8: DBG_TX * B9: DBG_RX * B10: LED 3 "On" * B11: LED 5 "RS458 Ping" * B12: LED 1 "Overheating" * B13: LED 6 "Control Error" * B14: LED 4 "Input Error" * B15: LED 2 "Output Error" */ GPIOB->MODER = AF(0) | AF(1) | AF(3) | OUT(2) | IN(4) | IN(5) | AF(6) | AF(7) | AF(8) | AF(9) | OUT(10) | OUT(11) | OUT(12) | OUT(13) | OUT(14) | OUT(15); GPIOB->AFR[0] = AFRL(0, 2) | AFRL(1, 2) | AFRL(3, 1) | AFRL(6, 6) | AFRL(7, 6); GPIOB->AFR[1] = AFRH(8, 4) | AFRH(9, 4); /* GPIOC: * C0-C3: (testpoint) * C4: RJ45 LED 4 * C5: RJ45 LED 3 * C6: Fuse monitor 7 * C7: Fuse monitor 2 * C8: Fuse monitor 5 * C9: (testpoint) * C10: Driver B high * C11-C15: (testpoint) */ GPIOC->MODER = IN(0) | IN(1) | IN(2) | IN(3) | IN(9) | IN(11) | IN(12) | IN(13) | IN(14) | IN(15) | OUT(4) | OUT(5) | IN(6) | IN(7) | IN(8) | AF(10); GPIOC->AFR[1] = AFRH(10, 2); /* GPIOD: * D0-D6: (testpoint) * D8: Fuse monitor 3 * D9: Fuse monitor 0 */ GPIOD->MODER = IN(0) | IN(1) | IN(2) | IN(3) | IN(4) | IN(5) | IN(6) | IN(8) | IN(9); TIM1->CCMR1 = (6<CCMR2 = (6<CCER = TIM_CCER_CC2E | TIM_CCER_CC2NE | TIM_CCER_CC3E | TIM_CCER_CC3NE; TIM1->BDTR = TIM_BDTR_MOE | (32<PSC = 0; TIM1->ARR = 256; TIM1->CR1 |= TIM_CR1_CEN; int i = 0; int j = 0; while (23) { i++; j++; i %= 6; j %= 4; delay_us(100000); set_rj45_leds(1 << j); set_status_leds(1 << i); } } uint32_t read_fuse_monitor() { uint32_t idr_a = GPIOA->IDR; uint32_t idr_c = GPIOC->IDR; uint32_t idr_d = GPIOD->IDR; int fm0 = !!(idr_d & (1<<9)); int fm1 = !!(idr_a & (1<<11)); int fm2 = !!(idr_c & (1<<7)); int fm3 = !!(idr_d & (1<<8)); int fm4 = !!(idr_a & (1<<15)); int fm5 = !!(idr_c & (1<<8)); int fm6 = !!(idr_a & (1<<8)); int fm7 = !!(idr_c & (1<<6)); return (fm0<<0) | (fm1<<1) | (fm2<<2) | (fm3<<3) | (fm4<<4) | (fm5<<5) | (fm6<<6) | (fm7<<7); } void set_rj45_leds(uint32_t leds) { leds = ~leds; if (leds&1) { GPIOB->BSRR = (1<<2); } else { GPIOB->BSRR = (1<<2)<<16; } if (leds&2) { GPIOA->BSRR = (1<<6); } else { GPIOA->BSRR = (1<<6)<<16; } if (leds&4) { GPIOC->BSRR = (1<<5); } else { GPIOC->BSRR = (1<<5)<<16; } if (leds&8) { GPIOC->BSRR = (1<<4); } else { GPIOC->BSRR = (1<<4)<<16; } } void set_status_leds(uint32_t leds) { GPIOB->BSRR = ((0x3f<<10)<<16) | (((~leds)&0x3f)<<10); } void SysTick_Handler() { sys_time_us += SYSTICK_INTERVAL_US; } void HardFault_Handler() { asm volatile ("bkpt"); } void delay_us(int duration_us) { while (duration_us--) { for (int i=0; i<3; i++) { asm volatile ("nop"); } } } void *memcpy(void *restrict dest, const void *restrict src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; for (; n; n--) { *d++ = *s++; } return dest; } void *memmove(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); } void *memset(void *dest, int c, size_t n) { unsigned char *d = dest; while (n--) { *d++ = c; } return dest; } size_t strlen(const char *s) { const char *start = s; while (*s) { s++; } return s - start; } void __libc_init_array (void) __attribute__((weak)); void __libc_init_array () { }