aboutsummaryrefslogtreecommitdiff
path: root/driver_fw/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver_fw/src/main.c')
-rw-r--r--driver_fw/src/main.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/driver_fw/src/main.c b/driver_fw/src/main.c
new file mode 100644
index 0000000..ae1bd08
--- /dev/null
+++ b/driver_fw/src/main.c
@@ -0,0 +1,252 @@
+
+#include <global.h>
+#include <string.h>
+
+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<<FLASH_ACR_LATENCY_Pos);
+ while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != (2<<FLASH_ACR_LATENCY_Pos)) {
+ /* wait for flash controller to acknowledge change. */
+ }
+ /* Configure PLL with multiplier 16, divisor 2 for "R" output, and enable "R" (sysclk) output */
+ RCC->PLLCFGR = (16<<RCC_PLLCFGR_PLLN_Pos) | (3<<RCC_PLLCFGR_PLLSRC_Pos) | (1<<RCC_PLLCFGR_PLLR_Pos) | RCC_PLLCFGR_PLLREN;
+ RCC->CR |= RCC_CR_PLLON;
+ while (!(RCC->CR & RCC_CR_PLLRDY)) {
+ /* wait for PLL to stabilize. */
+ }
+ /* Switch SYSCLK to PLL source. */
+ RCC->CFGR |= (2<<RCC_CFGR_SW_Pos);
+ while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != (2<<RCC_CFGR_SWS_Pos)) {
+ /* wait for RCC to switch over. */
+ }
+
+ RCC->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<<TIM_CCMR1_OC2M_Pos);
+ TIM1->CCMR2 = (6<<TIM_CCMR2_OC3M_Pos);
+ TIM1->CCER = TIM_CCER_CC2E | TIM_CCER_CC2NE | TIM_CCER_CC3E | TIM_CCER_CC3NE;
+ TIM1->BDTR = TIM_BDTR_MOE | (32<<TIM_BDTR_DTG_Pos);
+ TIM1->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 () {
+}