// Copyright (c) 2009 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#include <ctl_api.h>
#include <lm3s_cmsis.h>
#include <targets/LM3S.h>

void SystemInit (void) __attribute__ ((section (".init")));
extern uint32_t SystemCoreClock  __attribute__ ((section(".non_init")));

uint32_t SystemCoreClock;

#define delay2(count) { \
  volatile int i=0; \
  while (i++<count); \
}

void SystemInit()
{
  unsigned rcc = RCC;
  // enable MOSC and wait for a time for it to stablise
  rcc &= ~RCC_MOSCDIS_MASK;
  RCC = rcc;
  delay2(524288);
  // select 8mhz xtal, MOSC oscsrc and clear PLL pwrdn
  rcc &= ~(RCC_XTAL_MASK|RCC_OSCSRC_MASK|RCC_PWRDN_MASK);
  rcc |= (0xE<<RCC_XTAL_BIT)|(0<<RCC_OSCSRC_BIT)|(0<<RCC_PWRDN_BIT);
  RCC = rcc;
  // select sysdiv
  rcc &= ~(RCC_SYSDIV_MASK|RCC_USERSYSDIV_MASK);
  rcc |= (3<<RCC_SYSDIV_BIT)|(1<<RCC_USERSYSDIV_BIT); // PLL/4
  RCC = rcc;
  // wait for PLL to lock
  while (!(RIS & RIS_PLLRIS)); 
  // clear bypass
  rcc &= ~(RCC_BYPASS_MASK);   
  RCC = rcc;
  SystemCoreClock = 50000000; // 50 Mhz
}

void
delay(int count)
{
  volatile int i=0;
  while (i++<count);
}

void 
ctl_board_init(void)
{
  RCGC2 |= 1<<6; // clock GPIOG
  delay(1);
  GPIO_G_DIR |= 1<<2; // PG2 is output
  GPIO_G_DEN |= 1<<2; // PG2 is digital
}

void 
ctl_board_set_leds(unsigned set)
{
  if (set)
    *((&GPIO_G_DATA)+(1<<2)) = 0xff;
  else
    *((&GPIO_G_DATA)+(1<<2)) = 0;
}

static CTL_ISR_FN_t userButtonISR;

void
GPIO_Port_G_ISR(void)
{
  ctl_enter_isr();
  userButtonISR();  
  GPIO_G_ICR = (1<<7);
  ctl_exit_isr();
}

void 
ctl_board_on_button_pressed(CTL_ISR_FN_t buttonFn)
{
  userButtonISR = buttonFn;
  RCGC2 |= 1<<6; // clock GPIOG
  delay(1);
  GPIO_G_DEN |= 1<<7; // PG7 is digital
  GPIO_G_PUR |= 1<<7; // enable pull up
  GPIO_G_IM = 1<<7; // interrupt on PG7 edge
  ctl_set_priority(GPIOPortG_IRQn, 1);
  ctl_unmask_isr(GPIOPortG_IRQn);
}


