<commit_before>/*
 * This file is part of Espruino, a JavaScript interpreter for Microcontrollers
 *
 * Copyright (C) 2013 <NAME> <<EMAIL>>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * ----------------------------------------------------------------------------
 * Utilities - reimplementation of jshardware bits in minimal flash
 * ----------------------------------------------------------------------------
 */
#include "platform_config.h"
#include "usb_utils.h"
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "usb_istr.h"
#include "jshardware.h"

#define BUFFERMASK 8191
char rxBuffer[BUFFERMASK+1];
int rxHead=0, rxTail=0;
char txBuffer[BUFFERMASK+1];
int txHead=0, txTail=0;

uint16_t stmPin(Pin ipin) {
  JsvPinInfoPin pin = JSH_PIN0;
  if (JSH_PORTF_OFFSET >= 0 && ipin > JSH_PORTF_OFFSET) pin = ipin-JSH_PORTF_OFFSET;
  else if (JSH_PORTE_OFFSET >= 0 && ipin > JSH_PORTE_OFFSET) pin = ipin-JSH_PORTE_OFFSET;
  else if (JSH_PORTD_OFFSET >= 0 && ipin > JSH_PORTD_OFFSET) pin = ipin-JSH_PORTD_OFFSET;
  else if (JSH_PORTC_OFFSET >= 0 && ipin > JSH_PORTC_OFFSET) pin = ipin-JSH_PORTC_OFFSET;
  else if (JSH_PORTB_OFFSET >= 0 && ipin > JSH_PORTB_OFFSET) pin = ipin-JSH_PORTB_OFFSET;
  else if (JSH_PORTA_OFFSET >= 0 && ipin > JSH_PORTA_OFFSET) pin = ipin-JSH_PORTA_OFFSET;
  return 1 << pin;
}

GPIO_TypeDef *stmPort(Pin ipin) {
  if (JSH_PORTF_OFFSET >= 0 && ipin > JSH_PORTF_OFFSET) return GPIOF;
  else if (JSH_PORTE_OFFSET >= 0 && ipin > JSH_PORTE_OFFSET) return GPIOE;
  else if (JSH_PORTD_OFFSET >= 0 && ipin > JSH_PORTD_OFFSET) return GPIOD;
  else if (JSH_PORTC_OFFSET >= 0 && ipin > JSH_PORTC_OFFSET) return GPIOC;
  else if (JSH_PORTB_OFFSET >= 0 && ipin > JSH_PORTB_OFFSET) return GPIOB;
  //else if (ipin > JSH_PORTA_OFFSET) return GPIOA;
  return GPIOA;
}

bool jshPinGetValue(Pin pin) {
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = stmPin(pin);
#ifdef STM32API2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
#endif
  GPIO_Init(stmPort(pin), &GPIO_InitStructure);
  return GPIO_ReadInputDataBit(stmPort(pin), stmPin(pin)) != 0;
}

void jshPinOutput(Pin pin, bool value) {
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = stmPin(pin);
#ifdef STM32API2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
#endif
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(stmPort(pin), &GPIO_InitStructure);

#ifdef STM32API2
    if (value)
      GPIO_SetBits(stmPort(pin), stmPin(pin));
    else
      GPIO_ResetBits(stmPort(pin), stmPin(pin));
#else
    if (value)
      stmPort(pin)->BSRR = stmPin(pin);
    else
      stmPort(pin)->BRR = stmPin(pin);
#endif
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
  USB_Istr();
}

unsigned int SysTickUSBWatchdog = SYSTICKS_BEFORE_USB_DISCONNECT;

void jshKickUSBWatchdog() {
  SysTickUSBWatchdog = 0;
}

void SysTick_Handler(void) {
  if (SysTickUSBWatchdog < SYSTICKS_BEFORE_USB_DISCONNECT) {
    SysTickUSBWatchdog++;
  }
}

bool jshIsUSBSERIALConnected() {
  return SysTickUSBWatchdog < SYSTICKS_BEFORE_USB_DISCONNECT;
}

int jshGetCharToTransmit(IOEventFlags device) {
  if (txHead == txTail) return -1;
  char d = txBuffer[txTail];
  txTail = (txTail+1) & BUFFERMASK;
  return d;
}

void jshPushIOCharEvent(IOEventFlags channel, char charData) {
  rxBuffer[rxHead] = charData;
  rxHead = (rxHead+1) & BUFFERMASK;
  //if (rxHead == rxTail) weHaveOverFlowed();
}

bool jshHasEventSpaceForChars(int n) {
  return true;
}

int getc() {
  if (rxHead == rxTail) return -1;
  unsigned char d = (unsigned char)rxBuffer[rxTail];
  rxTail = (rxTail+1) & BUFFERMASK;
  return d;
}

unsigned char getc_blocking() {
  int c = getc();
  while (c<0) c=getc();
  return c;
}

void putc(char charData) {
  txBuffer[txHead] = charData;
  txHead = (txHead+1) & BUFFERMASK;
}

void initHardware() {
#if defined(STM32F3)
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
 RCC_AHBPeriphClockCmd( RCC_AHBPeriph_ADC12 |
                        RCC_AHBPeriph_GPIOA |
                        RCC_AHBPeriph_GPIOB |
                        RCC_AHBPeriph_GPIOC |
                        RCC_AHBPeriph_GPIOD |
                        RCC_AHBPeriph_GPIOE |
                        RCC_AHBPeriph_GPIOF, ENABLE);
#elif defined(STM32F2) || defined(STM32F4)
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
                        RCC_AHB1Periph_GPIOB |
                        RCC_AHB1Periph_GPIOC |
                        RCC_AHB1Periph_GPIOD |
                        RCC_AHB1Periph_GPIOE |
                        RCC_AHB1Periph_GPIOF |
                        RCC_AHB1Periph_GPIOG |
                        RCC_AHB1Periph_GPIOH, ENABLE);
#else
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
 RCC_APB2PeriphClockCmd(
       RCC_APB2Periph_ADC1 |
       RCC_APB2Periph_GPIOA |
       RCC_APB2Periph_GPIOB |
       RCC_APB2Periph_GPIOC |
       RCC_APB2Periph_GPIOD |
       RCC_APB2Periph_GPIOE |
       RCC_APB2Periph_GPIOF |
       RCC_APB2Periph_GPIOG |
       RCC_APB2Periph_AFIO, ENABLE);
#endif
#ifdef ESPRUINOBOARD
  // reclaim A13 and A14 for the LEDs
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // Disable JTAG/SWD so pins are available
#endif

  RCC_PCLK1Config(RCC_HCLK_Div8); // PCLK1 must be >8 Mhz for USB to work
  RCC_PCLK2Config(RCC_HCLK_Div16);

  // if button is not set, jump to this address
  if (jshPinGetValue(BTN1_PININDEX) != BTN1_ONSTATE) {
    unsigned int *ResetHandler = (unsigned int *)(0x08000000 + BOOTLOADER_SIZE + 4);
    void (*startPtr)() = *ResetHandler;
    startPtr();
  }

  /* System Clock */
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  SysTick_Config(SYSTICK_RANGE-1); // 24 bit
  NVIC_SetPriority(SysTick_IRQn, 0); // Super high priority


#ifdef USB
#if defined(STM32F1) || defined(STM32F3)
  USB_Init_Hardware();
  USB_Init();
#endif
#ifdef STM32F4
  USBD_Init(&USB_OTG_dev,
#ifdef USE_USB_OTG_HS
            USB_OTG_HS_CORE_ID,
#else
            USB_OTG_FS_CORE_ID,
#endif
            &USR_desc,
            &USBD_CDC_cb,
            &USR_cb);
#endif
#endif<commit_msg>change order of hardware init in bootloader<commit_after>/*
 * This file is part of Espruino, a JavaScript interpreter for Microcontrollers
 *
 * Copyright (C) 2013 <NAME> <<EMAIL>>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * ----------------------------------------------------------------------------
 * Utilities - reimplementation of jshardware bits in minimal flash
 * ----------------------------------------------------------------------------
 */
#include "platform_config.h"
#include "usb_utils.h"
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "usb_istr.h"
#include "jshardware.h"

#define BUFFERMASK 8191
char rxBuffer[BUFFERMASK+1];
int rxHead=0, rxTail=0;
char txBuffer[BUFFERMASK+1];
int txHead=0, txTail=0;

uint16_t stmPin(Pin ipin) {
  JsvPinInfoPin pin = JSH_PIN0;
  if (JSH_PORTF_OFFSET >= 0 && ipin > JSH_PORTF_OFFSET) pin = ipin-JSH_PORTF_OFFSET;
  else if (JSH_PORTE_OFFSET >= 0 && ipin > JSH_PORTE_OFFSET) pin = ipin-JSH_PORTE_OFFSET;
  else if (JSH_PORTD_OFFSET >= 0 && ipin > JSH_PORTD_OFFSET) pin = ipin-JSH_PORTD_OFFSET;
  else if (JSH_PORTC_OFFSET >= 0 && ipin > JSH_PORTC_OFFSET) pin = ipin-JSH_PORTC_OFFSET;
  else if (JSH_PORTB_OFFSET >= 0 && ipin > JSH_PORTB_OFFSET) pin = ipin-JSH_PORTB_OFFSET;
  else if (JSH_PORTA_OFFSET >= 0 && ipin > JSH_PORTA_OFFSET) pin = ipin-JSH_PORTA_OFFSET;
  return 1 << pin;
}

GPIO_TypeDef *stmPort(Pin ipin) {
  if (JSH_PORTF_OFFSET >= 0 && ipin > JSH_PORTF_OFFSET) return GPIOF;
  else if (JSH_PORTE_OFFSET >= 0 && ipin > JSH_PORTE_OFFSET) return GPIOE;
  else if (JSH_PORTD_OFFSET >= 0 && ipin > JSH_PORTD_OFFSET) return GPIOD;
  else if (JSH_PORTC_OFFSET >= 0 && ipin > JSH_PORTC_OFFSET) return GPIOC;
  else if (JSH_PORTB_OFFSET >= 0 && ipin > JSH_PORTB_OFFSET) return GPIOB;
  //else if (ipin > JSH_PORTA_OFFSET) return GPIOA;
  return GPIOA;
}

bool jshPinGetValue(Pin pin) {
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = stmPin(pin);
#ifdef STM32API2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
#endif
  GPIO_Init(stmPort(pin), &GPIO_InitStructure);
  return GPIO_ReadInputDataBit(stmPort(pin), stmPin(pin)) != 0;
}

void jshPinOutput(Pin pin, bool value) {
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = stmPin(pin);
#ifdef STM32API2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
#endif
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(stmPort(pin), &GPIO_InitStructure);

#ifdef STM32API2
    if (value)
      GPIO_SetBits(stmPort(pin), stmPin(pin));
    else
      GPIO_ResetBits(stmPort(pin), stmPin(pin));
#else
    if (value)
      stmPort(pin)->BSRR = stmPin(pin);
    else
      stmPort(pin)->BRR = stmPin(pin);
#endif
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
  USB_Istr();
}

unsigned int SysTickUSBWatchdog = SYSTICKS_BEFORE_USB_DISCONNECT;

void jshKickUSBWatchdog() {
  SysTickUSBWatchdog = 0;
}

void SysTick_Handler(void) {
  if (SysTickUSBWatchdog < SYSTICKS_BEFORE_USB_DISCONNECT) {
    SysTickUSBWatchdog++;
  }
}

bool jshIsUSBSERIALConnected() {
  return SysTickUSBWatchdog < SYSTICKS_BEFORE_USB_DISCONNECT;
}

int jshGetCharToTransmit(IOEventFlags device) {
  if (txHead == txTail) return -1;
  char d = txBuffer[txTail];
  txTail = (txTail+1) & BUFFERMASK;
  return d;
}

void jshPushIOCharEvent(IOEventFlags channel, char charData) {
  rxBuffer[rxHead] = charData;
  rxHead = (rxHead+1) & BUFFERMASK;
  //if (rxHead == rxTail) weHaveOverFlowed();
}

bool jshHasEventSpaceForChars(int n) {
  return true;
}

int getc() {
  if (rxHead == rxTail) return -1;
  unsigned char d = (unsigned char)rxBuffer[rxTail];
  rxTail = (rxTail+1) & BUFFERMASK;
  return d;
}

unsigned char getc_blocking() {
  int c = getc();
  while (c<0) c=getc();
  return c;
}

void putc(char charData) {
  txBuffer[txHead] = charData;
  txHead = (txHead+1) & BUFFERMASK;
}

void initHardware() {
#if defined(STM32F3)
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
 RCC_AHBPeriphClockCmd( RCC_AHBPeriph_ADC12 |
                        RCC_AHBPeriph_GPIOA |
                        RCC_AHBPeriph_GPIOB |
                        RCC_AHBPeriph_GPIOC |
                        RCC_AHBPeriph_GPIOD |
                        RCC_AHBPeriph_GPIOE |
                        RCC_AHBPeriph_GPIOF, ENABLE);
#elif defined(STM32F2) || defined(STM32F4)
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
                        RCC_AHB1Periph_GPIOB |
                        RCC_AHB1Periph_GPIOC |
                        RCC_AHB1Periph_GPIOD |
                        RCC_AHB1Periph_GPIOE |
                        RCC_AHB1Periph_GPIOF |
                        RCC_AHB1Periph_GPIOG |
                        RCC_AHB1Periph_GPIOH, ENABLE);
#else
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
 RCC_APB2PeriphClockCmd(
       RCC_APB2Periph_ADC1 |
       RCC_APB2Periph_GPIOA |
       RCC_APB2Periph_GPIOB |
       RCC_APB2Periph_GPIOC |
       RCC_APB2Periph_GPIOD |
       RCC_APB2Periph_GPIOE |
       RCC_APB2Periph_GPIOF |
       RCC_APB2Periph_GPIOG |
       RCC_APB2Periph_AFIO, ENABLE);
#endif

  // if button is not set, jump to this address
  if (jshPinGetValue(BTN1_PININDEX) != BTN1_ONSTATE) {
    unsigned int *ResetHandler = (unsigned int *)(0x08000000 + BOOTLOADER_SIZE + 4);
    void (*startPtr)() = *ResetHandler;
    startPtr();
  }

  RCC_PCLK1Config(RCC_HCLK_Div8); // PCLK1 must be >8 Mhz for USB to work
  RCC_PCLK2Config(RCC_HCLK_Div16);

#ifdef ESPRUINOBOARD
  // reclaim A13 and A14 for the LEDs
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // Disable JTAG/SWD so pins are available
#endif


  /* System Clock */
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  SysTick_Config(SYSTICK_RANGE-1); // 24 bit
  NVIC_SetPriority(SysTick_IRQn, 0); // Super high priority


#ifdef USB
#if defined(STM32F1) || defined(STM32F3)
  USB_Init_Hardware();
  USB_Init();
#endif
#ifdef STM32F4
  USBD_Init(&USB_OTG_dev,
#ifdef USE_USB_OTG_HS
            USB_OTG_HS_CORE_ID,
#else
            USB_OTG_FS_CORE_ID,
#endif
            &USR_desc,
            &USBD_CDC_cb,
            &USR_cb);
#endif
#endif
{'fraction_non_alphanumeric': 0.11800579356609239, 'fraction_numerical': 0.019820094526604666, 'mean_word_length': 3.3140414337389017, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7218636', 'n_tokens_mistral': 5248, 'n_tokens_neox': 4998, 'n_words': 967}