diff options
| -rw-r--r-- | software/led_fade/Makefile | 6 | ||||
| -rw-r--r-- | software/led_fade/led_fade.c | 160 | 
2 files changed, 166 insertions, 0 deletions
| diff --git a/software/led_fade/Makefile b/software/led_fade/Makefile new file mode 100644 index 0000000..c42049b --- /dev/null +++ b/software/led_fade/Makefile @@ -0,0 +1,6 @@ +TARGET = led_fade +C_SRCS += led_fade.c +CFLAGS += -O2 -fno-builtin-printf + +BSP_BASE = ../../bsp +include $(BSP_BASE)/env/common.mk diff --git a/software/led_fade/led_fade.c b/software/led_fade/led_fade.c new file mode 100644 index 0000000..775647a --- /dev/null +++ b/software/led_fade/led_fade.c @@ -0,0 +1,160 @@ +// See LICENSE for license details. + +// This is the program which ships on the HiFive1 +// board, executing out of SPI Flash at 0x20400000. + +#include <stdint.h> +#include "platform.h" + +static const char led_msg[] = "\a\n\r\n\r\ +55555555555555555555555555555555555555555555555\n\r\ +5555555 Are the LEDs Changing? [y/n]  555555555\n\r\ +55555555555555555555555555555555555555555555555\n\r"; + +static const char sifive_msg[] = "\n\r\ +\n\r\ +                SIFIVE, INC.\n\r\ +\n\r\ +         5555555555555555555555555\n\r\ +        5555                   5555\n\r\ +       5555                     5555\n\r\ +      5555                       5555\n\r\ +     5555       5555555555555555555555\n\r\ +    5555       555555555555555555555555\n\r\ +   5555                             5555\n\r\ +  5555                               5555\n\r\ + 5555                                 5555\n\r\ +5555555555555555555555555555          55555\n\r\ + 55555           555555555           55555\n\r\ +   55555           55555           55555\n\r\ +     55555           5           55555\n\r\ +       55555                   55555\n\r\ +         55555               55555\n\r\ +           55555           55555\n\r\ +             55555       55555\n\r\ +               55555   55555\n\r\ +                 555555555\n\r\ +                   55555\n\r\ +                     5\n\r\ +\n\r\ +               'led_fade' Demo \n\r\ +\n\r"; + +static void _putc(char c) { +  while ((int32_t) UART0_REG(UART_REG_TXFIFO) < 0); +  UART0_REG(UART_REG_TXFIFO) = c; +} + +int _getc(char * c){ +  int32_t val = (int32_t) UART0_REG(UART_REG_RXFIFO); +  if (val > 0) { +    *c =  val & 0xFF; +    return 1; +  } +  return 0; +} + + +static void _puts(const char * s) { +  while (*s != '\0'){ +    _putc(*s++); +  } +} + + +int main (void){ + +  // Run off 16 MHz Crystal for accuracy. +  PRCI_REG(PRCI_PLLCFG) = (PLL_REFSEL(1) | PLL_BYPASS(1)); +  PRCI_REG(PRCI_PLLCFG) |= (PLL_SEL(1)); +  // Turn off HFROSC to save power +  PRCI_REG(PRCI_HFROSCCFG) = 0; +   +  // Configure UART to print +  GPIO_REG(GPIO_OUTPUT_VAL) |= IOF0_UART0_MASK; +  GPIO_REG(GPIO_OUTPUT_EN)  |= IOF0_UART0_MASK; +  GPIO_REG(GPIO_IOF_SEL)    &= ~IOF0_UART0_MASK; +  GPIO_REG(GPIO_IOF_EN)     |= IOF0_UART0_MASK; + +  // 115200 Baud Rate +  UART0_REG(UART_REG_DIV) = 138; +  UART0_REG(UART_REG_TXCTRL) = UART_TXEN; +  UART0_REG(UART_REG_RXCTRL) = UART_RXEN; + +  // Wait a bit to avoid corruption on the UART. +  // (In some cases, switching to the IOF can lead +  // to output glitches, so need to let the UART +  // reciever time out and resynchronize to the real  +  // start of the stream. +  volatile int i=0; +  while(i < 10000){i++;} + +  _puts(sifive_msg); +  //_puts("Config String:\n\r"); +  //_puts(*((const char **) 0x100C)); +  //_puts("\n\r"); +  _puts(led_msg); +   +  uint16_t r=0xFF; +  uint16_t g=0; +  uint16_t b=0; +  char c = 0; +   +  // Set up RGB PWM +   +  PWM1_REG(PWM_CFG)   = 0; +  // To balance the power consumption, make one left, one right, and one center aligned. +  PWM1_REG(PWM_CFG)   = (PWM_CFG_ENALWAYS) | (PWM_CFG_CMP2CENTER); +  PWM1_REG(PWM_COUNT) = 0; +   +  // Period is approximately 244 Hz +  // the LEDs are intentionally left somewhat dim,  +  // as the full brightness can be painful to look at. +  PWM1_REG(PWM_CMP0)  = 0; + +  GPIO_REG(GPIO_IOF_SEL)    |= ( (1 << GREEN_LED_OFFSET) | (1 << BLUE_LED_OFFSET) | (1 << RED_LED_OFFSET)); +  GPIO_REG(GPIO_IOF_EN )    |= ( (1 << GREEN_LED_OFFSET) | (1 << BLUE_LED_OFFSET) | (1 << RED_LED_OFFSET)); +  GPIO_REG(GPIO_OUTPUT_XOR) &= ~( (1 << GREEN_LED_OFFSET) | (1 << BLUE_LED_OFFSET)); +  GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << RED_LED_OFFSET); + +  while(1){ +    volatile uint64_t *  now = (volatile uint64_t*)(CLINT_BASE_ADDR + CLINT_MTIME); +    volatile uint64_t then = *now + 100; +    while (*now < then) { } +   +    if(r > 0 && b == 0){ +      r--; +      g++; +    } +    if(g > 0 && r == 0){ +      g--; +      b++; +    } +    if(b > 0 && g == 0){ +      r++; +      b--; +    } +     +    uint32_t G = g; +    uint32_t R = r; +    uint32_t B = b; +     +    PWM1_REG(PWM_CMP1)  = G << 4;            // PWM is low on the left, GPIO is low on the left side, LED is ON on the left. +    PWM1_REG(PWM_CMP2)  = (B << 1) << 4;     // PWM is high on the middle, GPIO is low in the middle, LED is ON in the middle. +    PWM1_REG(PWM_CMP3)  = 0xFFFF - (R << 4); // PWM is low on the left, GPIO is low on the right, LED is on on the right. +   +    // Check for user input +    if (c == 0){ +      if (_getc(&c) != 0){ +        _putc(c); +        _puts("\n\r"); +         +        if ((c == 'y') || (c == 'Y')){ +          _puts("PASS\n\r"); +        } else{ +          _puts("FAIL\n\r"); +        } +      } +    } +  } +} | 
