From 0a83246ccf1d80e8de0cc527709cdc33574a57ca Mon Sep 17 00:00:00 2001 From: Emil A Date: Tue, 15 Feb 2022 10:08:56 -1000 Subject: [PATCH] Added i2c and spi1, spi2 to arty bsp --- bsp/freedom-e310-arty/core.dts | 20 +++ bsp/freedom-e310-arty/metal-inline.h | 48 +++++- bsp/freedom-e310-arty/metal-platform.h | 66 ++++++-- bsp/freedom-e310-arty/metal.h | 218 ++++++++++++++++++++++++- 4 files changed, 326 insertions(+), 26 deletions(-) diff --git a/bsp/freedom-e310-arty/core.dts b/bsp/freedom-e310-arty/core.dts index 1b06778b5..bbc21ec6c 100644 --- a/bsp/freedom-e310-arty/core.dts +++ b/bsp/freedom-e310-arty/core.dts @@ -124,6 +124,7 @@ interrupts = <6>; reg = <0x10014000 0x1000 0x20000000 0x20000000>; reg-names = "control", "mem"; + clocks = <&hfclk>; #address-cells = <1>; #size-cells = <1>; flash@0 { @@ -131,5 +132,24 @@ reg = <0x20000000 0x7a12000>; }; }; + spi2: spi@10034000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <6>; + reg = <0x10034000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + + }; + i2c0: i2c@10016000 { + compatible = "sifive,i2c0"; + interrupt-parent = <&plic>; + interrupts = <1>; + reg = <0x10016000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + }; + + }; }; diff --git a/bsp/freedom-e310-arty/metal-inline.h b/bsp/freedom-e310-arty/metal-inline.h index e6a85806b..38ecc2d90 100644 --- a/bsp/freedom-e310-arty/metal-inline.h +++ b/bsp/freedom-e310-arty/metal-inline.h @@ -71,13 +71,23 @@ extern __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_g /* --------------------- sifive_gpio_led ------------ */ - +extern __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led); +extern __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led); +extern __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led); /* --------------------- sifive_gpio_switch ------------ */ /* --------------------- sifive_i2c0 ------------ */ - +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c); +extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c); /* --------------------- sifive_prci0 ------------ */ @@ -231,11 +241,45 @@ struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, }; +/* From spi@10024000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10034000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + /* From serial@10013000 */ struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = { .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, }; +/* From led@0red */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0red = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0green */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0blue */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0blue */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_3 = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From i2c@10016000 */ +struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = { + .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c, +}; #endif /* METAL_INLINE_H*/ #endif /* ! ASSEMBLY */ diff --git a/bsp/freedom-e310-arty/metal-platform.h b/bsp/freedom-e310-arty/metal-platform.h index 4eb28b954..bd6ec43c7 100644 --- a/bsp/freedom-e310-arty/metal-platform.h +++ b/bsp/freedom-e310-arty/metal-platform.h @@ -92,23 +92,35 @@ #define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL #define METAL_SIFIVE_SPI0_0_SIZE 4096UL +/* From spi@10024000 */ +#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPIO0_1_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL +#define METAL_SIFIVE_SPIO0_1_SIZE 4096UL + +/* From spi@10034000 */ +#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPIO0_2_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_2_SIZE 4096UL + #define METAL_SIFIVE_SPI0 #define METAL_SIFIVE_SPI0_SCKDIV 0UL -#define METAL_SIFIVE_SPI0_SCKMODE 4UL -#define METAL_SIFIVE_SPI0_CSID 16UL -#define METAL_SIFIVE_SPI0_CSDEF 20UL -#define METAL_SIFIVE_SPI0_CSMODE 24UL -#define METAL_SIFIVE_SPI0_DELAY0 40UL -#define METAL_SIFIVE_SPI0_DELAY1 44UL -#define METAL_SIFIVE_SPI0_FMT 64UL -#define METAL_SIFIVE_SPI0_TXDATA 72UL -#define METAL_SIFIVE_SPI0_RXDATA 76UL -#define METAL_SIFIVE_SPI0_TXMARK 80UL -#define METAL_SIFIVE_SPI0_RXMARK 84UL -#define METAL_SIFIVE_SPI0_FCTRL 96UL -#define METAL_SIFIVE_SPI0_FFMT 100UL -#define METAL_SIFIVE_SPI0_IE 112UL -#define METAL_SIFIVE_SPI0_IP 116UL +#define METAL_SIFIVE_SPI0_SCKMODE 4UL //0x04 +#define METAL_SIFIVE_SPI0_CSID 16UL //0x10 +#define METAL_SIFIVE_SPI0_CSDEF 20UL //0x14 +#define METAL_SIFIVE_SPI0_CSMODE 24UL //0x18 +#define METAL_SIFIVE_SPI0_DELAY0 40UL //0x28 +#define METAL_SIFIVE_SPI0_DELAY1 44UL //0x2C +#define METAL_SIFIVE_SPI0_FMT 64UL //0x40 +#define METAL_SIFIVE_SPI0_TXDATA 72UL //0x48 +#define METAL_SIFIVE_SPI0_RXDATA 76UL //0x4C +#define METAL_SIFIVE_SPI0_TXMARK 80UL //0x50 +#define METAL_SIFIVE_SPI0_RXMARK 84UL //0x54 +#define METAL_SIFIVE_SPI0_FCTRL 96UL //0x60 +#define METAL_SIFIVE_SPI0_FFMT 100UL //0x64 +#define METAL_SIFIVE_SPI0_IE 112UL //0x70 +#define METAL_SIFIVE_SPI0_IP 116UL //0x74 /* From serial@10013000 */ #define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL @@ -125,4 +137,28 @@ #define METAL_SIFIVE_UART0_IP 20UL #define METAL_SIFIVE_UART0_DIV 24UL +/* From led@0red */ + +/* From led@0green */ + +/* From led@0blue */ + +#define METAL_SIFIVE_GPIO_LEDS + +/* From i2c@10016000 */ +#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL +#define METAL_SIFIVE_I2C0_0_SIZE 4096UL + +#define METAL_SIFIVE_I2C0 +#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL +#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL +#define METAL_SIFIVE_I2C0_CONTROL 8UL +#define METAL_SIFIVE_I2C0_TRANSMIT 12UL +#define METAL_SIFIVE_I2C0_RECEIVE 12UL +#define METAL_SIFIVE_I2C0_COMMAND 16UL +#define METAL_SIFIVE_I2C0_STATUS 16UL + + #endif /* METAL_PLATFORM_H*/ diff --git a/bsp/freedom-e310-arty/metal.h b/bsp/freedom-e310-arty/metal.h index ed4695180..ccb77ba53 100644 --- a/bsp/freedom-e310-arty/metal.h +++ b/bsp/freedom-e310-arty/metal.h @@ -65,7 +65,7 @@ #define METAL_MAX_GPIO_INTERRUPTS 16 -#define METAL_MAX_I2C0_INTERRUPTS 0 +#define METAL_MAX_I2C0_INTERRUPTS 1 #define __METAL_PWM_10015000_INTERRUPTS 4 @@ -91,6 +91,9 @@ #include #include #include +#include +#include +#include /* From clock@0 */ extern struct __metal_driver_fixed_clock __metal_dt_clock_0; @@ -124,10 +127,33 @@ extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000; /* From spi@10014000 */ extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; +/* From spi@10024000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000; + +/* From spi@10014000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000; + + /* From serial@10013000 */ extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; +/* From led@0red */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; + +/* From led@0green */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; + +/* From led@0blue */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; + +/* From led@3 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_3; +/* From button@0 */ +extern struct __metal_driver_sifive_gpio_button __metal_dt_button_0; + +/* From 12c@10016000 */ +extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000; /* --------------------- fixed_clock ------------ */ static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock) @@ -513,19 +539,152 @@ static __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_g } } +static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return 1; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return 2; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return 3; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_3) { + return 14; + } + else { + return 0; + } +} +static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return "LD0red"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return "LD0green"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return "LD0blue"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_3) { + return "LD3"; + } + else { + return ""; + } +} /* --------------------- sifive_gpio_button ------------ */ /* --------------------- sifive_gpio_led ------------ */ +static __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_3) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + /* --------------------- sifive_gpio_switch ------------ */ /* --------------------- sifive_i2c0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct metal_clock *)&__metal_dt_clock_0.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 12288; + } + else { + return 0; + } +} +static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c) +{ + return METAL_MAX_I2C0_INTERRUPTS; +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 52; + } + else { + return 0; + } +} /* --------------------- sifive_prci0 ------------ */ @@ -657,6 +816,12 @@ static __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct m if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS; } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000){ + return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000){ + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } else { return 0; } @@ -667,6 +832,12 @@ static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct m if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return METAL_SIFIVE_SPI0_10014000_SIZE; } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000){ + return METAL_SIFIVE_SPI0_10034000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000){ + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } else { return 0; } @@ -675,7 +846,13 @@ static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct m static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) { if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { - return NULL; + return (struct metal_clock *)&__metal_dt_clock_0.clock; + } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000){ + return (struct metal_clock *)&__metal_dt_clock_0.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000){ + return (struct metal_clock *)&__metal_dt_clock_0.clock; } else { return 0; @@ -685,7 +862,13 @@ static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct m static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) { if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { - return NULL; + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000){ + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000){ + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } else { return 0; @@ -697,6 +880,12 @@ static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selecto if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return 0; } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000){ + return 0; + } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000){ + return 0; + } else { return 0; } @@ -707,6 +896,12 @@ static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selecto if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return 0; } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000){ + return 60; + } + else if((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000){ + return 4227858432; + } else { return 0; } @@ -873,18 +1068,21 @@ struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] __attribute__((weak)) struct __metal_driver_sifive_gpio_button *__metal_button_table[] __attribute__((weak)) = { NULL }; -#define __METAL_DT_MAX_LEDS 0 +#define __METAL_DT_MAX_LEDS 4 struct __metal_driver_sifive_gpio_led *__metal_led_table[] __attribute__((weak)) = { - NULL }; + &__metal_dt_led_0red, + &__metal_dt_led_0green, + &__metal_dt_led_0blue, + &__metal_dt_led_3}; #define __METAL_DT_MAX_SWITCHES 0 struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] __attribute__((weak)) = { NULL }; -#define __METAL_DT_MAX_I2CS 0 +#define __METAL_DT_MAX_I2CS 1 struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] __attribute__((weak)) = { - NULL }; + &__metal_dt_i2c_10016000}; #define __METAL_DT_MAX_PWMS 1 struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] __attribute__((weak)) = { @@ -894,10 +1092,12 @@ struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] __attribute__((weak)) = struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] __attribute__((weak)) = { NULL }; -#define __METAL_DT_MAX_SPIS 1 +#define __METAL_DT_MAX_SPIS 3 struct __metal_driver_sifive_spi0 *__metal_spi_table[] __attribute__((weak)) = { - &__metal_dt_spi_10014000}; + &__metal_dt_spi_10014000, + &__metal_dt_spi_10024000, + &__metal_dt_spi_10034000}; #define __METAL_DT_MAX_UARTS 1