move things around and add efm8 and efm32 builds

This commit is contained in:
Conor Patrick
2018-06-27 21:39:19 -04:00
parent e446e29318
commit fb9a592d50
84 changed files with 22289 additions and 419 deletions

366
efm8/src/InitDevice.c Normal file
View File

@@ -0,0 +1,366 @@
//=========================================================
// src/InitDevice.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include <SI_EFM8UB1_Register_Enums.h>
#include "InitDevice.h"
// USER PROTOTYPES
// USER FUNCTIONS
// $[Library Includes]
#include "efm8_usb.h"
#include "descriptors.h"
#include "usb_0.h"
// [Library Includes]$
//==============================================================================
// enter_DefaultMode_from_RESET
//==============================================================================
extern void enter_DefaultMode_from_RESET(void) {
// $[Config Calls]
// Save the SFRPAGE
uint8_t SFRPAGE_save = SFRPAGE;
WDT_0_enter_DefaultMode_from_RESET();
PORTS_0_enter_DefaultMode_from_RESET();
PBCFG_0_enter_DefaultMode_from_RESET();
CIP51_0_enter_DefaultMode_from_RESET();
CLOCK_0_enter_DefaultMode_from_RESET();
TIMER16_2_enter_DefaultMode_from_RESET();
TIMER16_3_enter_DefaultMode_from_RESET();
TIMER_SETUP_0_enter_DefaultMode_from_RESET();
UARTE_1_enter_DefaultMode_from_RESET();
INTERRUPT_0_enter_DefaultMode_from_RESET();
USBLIB_0_enter_DefaultMode_from_RESET();
// Restore the SFRPAGE
SFRPAGE = SFRPAGE_save;
// [Config Calls]$
}
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void) {
// $[EIE1 - Extended Interrupt Enable 1]
// [EIE1 - Extended Interrupt Enable 1]$
// $[EIE2 - Extended Interrupt Enable 2]
// [EIE2 - Extended Interrupt Enable 2]$
// $[EIP1H - Extended Interrupt Priority 1 High]
// [EIP1H - Extended Interrupt Priority 1 High]$
// $[EIP1 - Extended Interrupt Priority 1 Low]
// [EIP1 - Extended Interrupt Priority 1 Low]$
// $[EIP2 - Extended Interrupt Priority 2]
// [EIP2 - Extended Interrupt Priority 2]$
// $[EIP2H - Extended Interrupt Priority 2 High]
// [EIP2H - Extended Interrupt Priority 2 High]$
// $[IE - Interrupt Enable]
/***********************************************************************
- Enable each interrupt according to its individual mask setting
- Disable external interrupt 0
- Disable external interrupt 1
- Disable all SPI0 interrupts
- Disable all Timer 0 interrupt
- Disable all Timer 1 interrupt
- Disable Timer 2 interrupt
- Disable UART0 interrupt
***********************************************************************/
SFRPAGE = 0x00;
IE = IE_EA__ENABLED | IE_EX0__DISABLED | IE_EX1__DISABLED
| IE_ESPI0__DISABLED | IE_ET0__DISABLED | IE_ET1__DISABLED
| IE_ET2__DISABLED | IE_ES0__DISABLED;
// [IE - Interrupt Enable]$
// $[IP - Interrupt Priority]
// [IP - Interrupt Priority]$
// $[IPH - Interrupt Priority High]
// [IPH - Interrupt Priority High]$
}
extern void USBLIB_0_enter_DefaultMode_from_RESET(void) {
// $[USBD Init]
USBD_Init (&initstruct);
// [USBD Init]$
}
extern void CLOCK_0_enter_DefaultMode_from_RESET(void) {
// $[HFOSC1 Setup]
// Ensure SYSCLK is > 24 MHz before switching to HFOSC1
SFRPAGE = 0x00;
CLKSEL = CLKSEL_CLKSL__HFOSC0 | CLKSEL_CLKDIV__SYSCLK_DIV_1;
while ((CLKSEL & CLKSEL_DIVRDY__BMASK) == CLKSEL_DIVRDY__NOT_READY)
;
// [HFOSC1 Setup]$
// $[CLKSEL - Clock Select]
/***********************************************************************
- Clock derived from the Internal High Frequency Oscillator 1
- SYSCLK is equal to selected clock source divided by 1
***********************************************************************/
CLKSEL = CLKSEL_CLKSL__HFOSC1 | CLKSEL_CLKDIV__SYSCLK_DIV_1;
while ((CLKSEL & CLKSEL_DIVRDY__BMASK) == CLKSEL_DIVRDY__NOT_READY)
;
// [CLKSEL - Clock Select]$
}
extern void WDT_0_enter_DefaultMode_from_RESET(void) {
// $[WDTCN - Watchdog Timer Control]
SFRPAGE = 0x00;
//Disable Watchdog with key sequence
WDTCN = 0xDE; //First key
WDTCN = 0xAD; //Second key
// [WDTCN - Watchdog Timer Control]$
}
extern void CIP51_0_enter_DefaultMode_from_RESET(void) {
// $[PFE0CN - Prefetch Engine Control]
/***********************************************************************
- Enable the prefetch engine
- SYSCLK < 50 MHz
***********************************************************************/
SFRPAGE = 0x10;
PFE0CN = PFE0CN_PFEN__ENABLED | PFE0CN_FLRT__SYSCLK_BELOW_50_MHZ;
// [PFE0CN - Prefetch Engine Control]$
}
extern void PBCFG_0_enter_DefaultMode_from_RESET(void) {
// $[XBR2 - Port I/O Crossbar 2]
/***********************************************************************
- Weak Pullups enabled
- Crossbar enabled
- UART1 TX1 RX1 routed to Port pins
- UART1 RTS1 unavailable at Port pin
- UART1 CTS1 unavailable at Port pin
***********************************************************************/
XBR2 = XBR2_WEAKPUD__PULL_UPS_ENABLED | XBR2_XBARE__ENABLED
| XBR2_URT1E__ENABLED | XBR2_URT1RTSE__DISABLED
| XBR2_URT1CTSE__DISABLED;
// [XBR2 - Port I/O Crossbar 2]$
// $[PRTDRV - Port Drive Strength]
// [PRTDRV - Port Drive Strength]$
// $[XBR0 - Port I/O Crossbar 0]
// [XBR0 - Port I/O Crossbar 0]$
// $[XBR1 - Port I/O Crossbar 1]
// [XBR1 - Port I/O Crossbar 1]$
}
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void) {
// $[CKCON0 - Clock Control 0]
/***********************************************************************
- System clock divided by 12
- Counter/Timer 0 uses the clock defined by the prescale field, SCA
- Timer 2 high byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 2 low byte uses the system clock
- Timer 3 high byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 3 low byte uses the system clock
- Timer 1 uses the clock defined by the prescale field, SCA
***********************************************************************/
CKCON0 = CKCON0_SCA__SYSCLK_DIV_12 | CKCON0_T0M__PRESCALE
| CKCON0_T2MH__EXTERNAL_CLOCK | CKCON0_T2ML__SYSCLK
| CKCON0_T3MH__EXTERNAL_CLOCK | CKCON0_T3ML__SYSCLK
| CKCON0_T1M__PRESCALE;
// [CKCON0 - Clock Control 0]$
// $[CKCON1 - Clock Control 1]
// [CKCON1 - Clock Control 1]$
// $[TMOD - Timer 0/1 Mode]
// [TMOD - Timer 0/1 Mode]$
// $[TCON - Timer 0/1 Control]
// [TCON - Timer 0/1 Control]$
}
extern void UARTE_1_enter_DefaultMode_from_RESET(void) {
// $[SBCON1 - UART1 Baud Rate Generator Control]
/***********************************************************************
- Enable the baud rate generator
- Prescaler = 1
***********************************************************************/
SFRPAGE = 0x20;
SBCON1 = SBCON1_BREN__ENABLED | SBCON1_BPS__DIV_BY_1;
// [SBCON1 - UART1 Baud Rate Generator Control]$
// $[SMOD1 - UART1 Mode]
// [SMOD1 - UART1 Mode]$
// $[UART1FCN0 - UART1 FIFO Control 0]
// [UART1FCN0 - UART1 FIFO Control 0]$
// $[SBRLH1 - UART1 Baud Rate Generator High Byte]
/***********************************************************************
- UART1 Baud Rate Reload High = 0xFF
***********************************************************************/
SBRLH1 = (0xFF << SBRLH1_BRH__SHIFT);
// [SBRLH1 - UART1 Baud Rate Generator High Byte]$
// $[SBRLL1 - UART1 Baud Rate Generator Low Byte]
/***********************************************************************
- UART1 Baud Rate Reload Low = 0x30
***********************************************************************/
SBRLL1 = (0x30 << SBRLL1_BRL__SHIFT);
// [SBRLL1 - UART1 Baud Rate Generator Low Byte]$
// $[UART1LIN - UART1 LIN Configuration]
// [UART1LIN - UART1 LIN Configuration]$
// $[SCON1 - UART1 Serial Port Control]
/***********************************************************************
- UART1 reception enabled
***********************************************************************/
SCON1 |= SCON1_REN__RECEIVE_ENABLED;
// [SCON1 - UART1 Serial Port Control]$
// $[UART1FCN1 - UART1 FIFO Control 1]
// [UART1FCN1 - UART1 FIFO Control 1]$
}
extern void TIMER16_2_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR2CN0_TR2_save;
TMR2CN0_TR2_save = TMR2CN0 & TMR2CN0_TR2__BMASK;
// Stop Timer
TMR2CN0 &= ~(TMR2CN0_TR2__BMASK);
// [Timer Initialization]$
// $[TMR2CN1 - Timer 2 Control 1]
// [TMR2CN1 - Timer 2 Control 1]$
// $[TMR2CN0 - Timer 2 Control]
// [TMR2CN0 - Timer 2 Control]$
// $[TMR2H - Timer 2 High Byte]
// [TMR2H - Timer 2 High Byte]$
// $[TMR2L - Timer 2 Low Byte]
// [TMR2L - Timer 2 Low Byte]$
// $[TMR2RLH - Timer 2 Reload High Byte]
/***********************************************************************
- Timer 2 Reload High Byte = 0x44
***********************************************************************/
TMR2RLH = (0x44 << TMR2RLH_TMR2RLH__SHIFT);
// [TMR2RLH - Timer 2 Reload High Byte]$
// $[TMR2RLL - Timer 2 Reload Low Byte]
/***********************************************************************
- Timer 2 Reload Low Byte = 0x80
***********************************************************************/
TMR2RLL = (0x80 << TMR2RLL_TMR2RLL__SHIFT);
// [TMR2RLL - Timer 2 Reload Low Byte]$
// $[TMR2CN0]
/***********************************************************************
- Start Timer 2 running
***********************************************************************/
TMR2CN0 |= TMR2CN0_TR2__RUN;
// [TMR2CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR2CN0 |= TMR2CN0_TR2_save;
// [Timer Restoration]$
}
extern void TIMER16_3_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR3CN0_TR3_save;
TMR3CN0_TR3_save = TMR3CN0 & TMR3CN0_TR3__BMASK;
// Stop Timer
TMR3CN0 &= ~(TMR3CN0_TR3__BMASK);
// [Timer Initialization]$
// $[TMR3CN1 - Timer 3 Control 1]
// [TMR3CN1 - Timer 3 Control 1]$
// $[TMR3CN0 - Timer 3 Control]
// [TMR3CN0 - Timer 3 Control]$
// $[TMR3H - Timer 3 High Byte]
// [TMR3H - Timer 3 High Byte]$
// $[TMR3L - Timer 3 Low Byte]
// [TMR3L - Timer 3 Low Byte]$
// $[TMR3RLH - Timer 3 Reload High Byte]
// [TMR3RLH - Timer 3 Reload High Byte]$
// $[TMR3RLL - Timer 3 Reload Low Byte]
// [TMR3RLL - Timer 3 Reload Low Byte]$
// $[TMR3CN0]
// [TMR3CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR3CN0 |= TMR3CN0_TR3_save;
// [Timer Restoration]$
}
extern void PORTS_0_enter_DefaultMode_from_RESET(void) {
// $[P0 - Port 0 Pin Latch]
// [P0 - Port 0 Pin Latch]$
// $[P0MDOUT - Port 0 Output Mode]
/***********************************************************************
- P0.0 output is push-pull
- P0.1 output is open-drain
- P0.2 output is open-drain
- P0.3 output is open-drain
- P0.4 output is open-drain
- P0.5 output is open-drain
- P0.6 output is open-drain
- P0.7 output is open-drain
***********************************************************************/
P0MDOUT = P0MDOUT_B0__PUSH_PULL | P0MDOUT_B1__OPEN_DRAIN
| P0MDOUT_B2__OPEN_DRAIN | P0MDOUT_B3__OPEN_DRAIN
| P0MDOUT_B4__OPEN_DRAIN | P0MDOUT_B5__OPEN_DRAIN
| P0MDOUT_B6__OPEN_DRAIN | P0MDOUT_B7__OPEN_DRAIN;
// [P0MDOUT - Port 0 Output Mode]$
// $[P0MDIN - Port 0 Input Mode]
// [P0MDIN - Port 0 Input Mode]$
// $[P0SKIP - Port 0 Skip]
// [P0SKIP - Port 0 Skip]$
// $[P0MASK - Port 0 Mask]
// [P0MASK - Port 0 Mask]$
// $[P0MAT - Port 0 Match]
// [P0MAT - Port 0 Match]$
}
extern void PORTS_1_enter_DefaultMode_from_RESET(void) {
}
extern void PORTS_2_enter_DefaultMode_from_RESET(void) {
}

203
efm8/src/SILABS_STARTUP.A51 Normal file
View File

@@ -0,0 +1,203 @@
$NOMOD51
;------------------------------------------------------------------------------
; This file is part of the C51 Compiler package
; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
; Version 8.01
;
; *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
; STARTUP.A51: This code is executed after processor reset.
;
; To translate this file use A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use the following
; Lx51 invocation:
;
; Lx51 your object file list, STARTUP.OBJ controls
;
;------------------------------------------------------------------------------
;
; User-defined <h> Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; <o> IDATALEN: IDATA memory size <0x0-0x100>
; <i> Note: The absolute start-address of IDATA memory is always 0
; <i> The IDATA space overlaps physically the DATA and BIT areas.
IDATALEN EQU 80H
;
; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of XDATA memory
XDATASTART EQU 0
;
; <o> XDATALEN: XDATA memory size <0x0-0xFFFF>
; <i> The length of XDATA memory in bytes.
XDATALEN EQU 0
;
; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of PDATA memory
PDATASTART EQU 0H
;
; <o> PDATALEN: PDATA memory size <0x0-0xFF>
; <i> The length of PDATA memory in bytes.
PDATALEN EQU 0H
;
;</h>
;------------------------------------------------------------------------------
;
;<h> Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
;
; <h> Stack Space for reentrant functions in the SMALL model.
; <q> IBPSTACK: Enable SMALL model reentrant stack
; <i> Stack space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
; <i> Set the top of the stack to the highest location.
IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the LARGE model.
; <q> XBPSTACK: Enable LARGE model reentrant stack
; <i> Stack space for reentrant functions in the LARGE model.
XBPSTACK EQU 0 ; set to 1 if large reentrant is used.
; <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the COMPACT model.
; <q> PBPSTACK: Enable COMPACT model reentrant stack
; <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.
;
; <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;</h>
;------------------------------------------------------------------------------
;
; Memory Page for Using the Compact Model with 64 KByte xdata RAM
; <e>Compact Model Page Definition
;
; <i>Define the XDATA page used for PDATA variables.
; <i>PPAGE must conform with the PPAGE set in the linker invocation.
;
; Enable pdata memory page initalization
PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
;
; <o> PPAGE number <0x0-0xFF>
; <i> uppermost 256-byte address of the page used for PDATA variables.
PPAGE EQU 0
;
; <o> SFR address which supplies uppermost address byte <0x0-0xFF>
; <i> most 8051 variants use P2 as uppermost address byte
PPAGE_SFR DATA 0A0H
;
; </e>
;------------------------------------------------------------------------------
; Standard SFR Symbols
ACC DATA 0E0H
B DATA 0F0H
SP DATA 81H
DPL DATA 82H
DPH DATA 83H
NAME ?C_STARTUP
?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA
RSEG ?STACK
DS 1
EXTRN CODE (?C_START)
PUBLIC ?C_STARTUP
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
$IF (SILABS_STARTUP = 1)
EXTRN CODE (SiLabs_Startup)
LCALL SiLabs_Startup
$ENDIF
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF XDATALEN <> 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV R6,#(HIGH (XDATALEN)) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV PPAGE_SFR,#PPAGE
ENDIF
IF PDATALEN <> 0
MOV R0,#LOW (PDATASTART)
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV ?C_IBP,#LOW IBPSTACKTOP
ENDIF
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF
MOV SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
;<h> Code Banking
; <q> Select Bank 0 for L51_BANK.A51 Mode 4
$IF (USE_BANKING = 1)
; <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
EXTRN CODE (?B_SWITCH0)
CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
$ENDIF
;</h>
LJMP ?C_START
END

145
efm8/src/callback.c Normal file
View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2016, Conor Patrick
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdio.h>
#include "descriptors.h"
#define UNUSED(expr) do { (void)(expr); } while (0)
#define HID_INTERFACE_INDEX 0
uint8_t tmpBuffer;
void USBD_ResetCb(void) {
// u2f_print_ev("USBD_ResetCb\r\n");
}
void USBD_DeviceStateChangeCb(USBD_State_TypeDef oldState,
USBD_State_TypeDef newState) {
UNUSED(oldState);
UNUSED(newState);
// u2f_print_ev("USBD_DeviceStateChangeCb\r\n");
}
bool USBD_IsSelfPoweredCb(void) {
return false;
}
// Necessary routine for USB HID
USB_Status_TypeDef USBD_SetupCmdCb(
SI_VARIABLE_SEGMENT_POINTER(setup, USB_Setup_TypeDef, MEM_MODEL_SEG)) {
USB_Status_TypeDef retVal = USB_STATUS_REQ_UNHANDLED;
if ((setup->bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)) {
// A HID device must extend the standard GET_DESCRIPTOR command
// with support for HID descriptors.
switch (setup->bRequest) {
case GET_DESCRIPTOR:
if (setup->wIndex == 0)
{
if ((setup->wValue >> 8) == USB_HID_REPORT_DESCRIPTOR) {
USBD_Write(EP0, ReportDescriptor0,
EFM8_MIN(sizeof(ReportDescriptor0), setup->wLength),
false);
retVal = USB_STATUS_OK;
} else if ((setup->wValue >> 8) == USB_HID_DESCRIPTOR) {
USBD_Write(EP0, (&configDesc[18]),
EFM8_MIN(USB_HID_DESCSIZE, setup->wLength), false);
retVal = USB_STATUS_OK;
}
}
break;
}
}
else if ((setup->bmRequestType.Type == USB_SETUP_TYPE_CLASS)
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)
&& (setup->wIndex == HID_INTERFACE_INDEX))
{
// Implement the necessary HID class specific commands.
switch (setup->bRequest)
{
case USB_HID_SET_IDLE:
if (((setup->wValue & 0xFF) == 0) // Report ID
&& (setup->wLength == 0)
&& (setup->bmRequestType.Direction != USB_SETUP_DIR_IN))
{
retVal = USB_STATUS_OK;
}
break;
case USB_HID_GET_IDLE:
if ((setup->wValue == 0) // Report ID
&& (setup->wLength == 1)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN))
{
tmpBuffer = 24;
USBD_Write(EP0, &tmpBuffer, 1, false);
retVal = USB_STATUS_OK;
}
break;
default:
break;
}
}
return retVal;
}
uint8_t hidmsgbuf[64];
uint16_t USBD_XferCompleteCb(uint8_t epAddr, USB_Status_TypeDef status,
uint16_t xferred, uint16_t remaining ) {
UNUSED(status);
UNUSED(xferred);
UNUSED(remaining);
if (epAddr == EP1OUT)
{
// set_app_u2f_hid_msg((struct u2f_hid_msg *) hidmsgbuf );
}
return 0;
}

174
efm8/src/descriptors.c Normal file
View File

@@ -0,0 +1,174 @@
//=============================================================================
// src/descriptors.c: generated by Hardware Configurator
//
// This file is only generated if it does not exist. Modifications in this file
// will persist even if Configurator generates code. To refresh this file,
// you must first delete it and then regenerate code.
//=============================================================================
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <si_toolchain.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <efm8_usb.h>
#include "descriptors.h"
#ifdef __cplusplus
extern "C" {
#endif
// HID Report Descriptor for Interface 0
SI_SEGMENT_VARIABLE(ReportDescriptor0[34],
const uint8_t,
SI_SEG_CODE) =
{
0x06, 0xd0, 0xf1,// USAGE_PAGE (FIDO Alliance)
0x09, 0x01,// USAGE (Keyboard)
0xa1, 0x01,// COLLECTION (Application)
0x09, 0x20, // USAGE (Input Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x21, // USAGE(Output Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0,// END_COLLECTION
};
SI_SEGMENT_VARIABLE(deviceDesc[],
const USB_DeviceDescriptor_TypeDef,
SI_SEG_CODE) =
{
USB_DEVICE_DESCSIZE, // bLength
USB_DEVICE_DESCRIPTOR,// bLength
htole16(0x0200),// bcdUSB
0,// bDeviceClass
0,// bDeviceSubClass
0,// bDeviceProtocol
64,// bMaxPacketSize
USB_VENDOR_ID,// idVendor
USB_PRODUCT_ID,// idProduct
htole16(0x0100),// bcdDevice
1,// iManufacturer
2,// iProduct
3,// iSerialNumber
1,// bNumConfigurations
};
SI_SEGMENT_VARIABLE(configDesc[],
const uint8_t,
SI_SEG_CODE) =
{
USB_CONFIG_DESCSIZE, // bLength
USB_CONFIG_DESCRIPTOR,// bLength
0x29,// wTotalLength(LSB)
0x00,// wTotalLength(MSB)
1,// bNumInterfaces
1,// bConfigurationValue
0,// iConfiguration
CONFIG_DESC_BM_RESERVED_D7,// bmAttrib: Bus powered
CONFIG_DESC_MAXPOWER_mA(100),// bMaxPower: 100 mA
//Interface 0 Descriptor
USB_INTERFACE_DESCSIZE,// bLength
USB_INTERFACE_DESCRIPTOR,// bDescriptorType
0,// bInterfaceNumber
0,// bAlternateSetting
2,// bNumEndpoints
3,// bInterfaceClass: HID (Human Interface Device)
0,// bInterfaceSubClass
0,// bInterfaceProtocol
4,// iInterface
//HID Descriptor
USB_HID_DESCSIZE,// bLength
USB_HID_DESCRIPTOR,// bLength
0x11,// bcdHID (LSB)
0x01,// bcdHID (MSB)
0,// bCountryCode
1,// bNumDescriptors
USB_HID_REPORT_DESCRIPTOR,// bDescriptorType
sizeof( ReportDescriptor0 ),// wDescriptorLength(LSB)
sizeof( ReportDescriptor0 )>>8,// wDescriptorLength(MSB)
//Endpoint 1 IN Descriptor
USB_ENDPOINT_DESCSIZE,// bLength
USB_ENDPOINT_DESCRIPTOR,// bDescriptorType
0x81,// bEndpointAddress
USB_EPTYPE_INTR,// bAttrib
HID_PACKET_SIZE,// wMaxPacketSize (LSB)
0x00,// wMaxPacketSize (MSB)
5,// bInterval
//Endpoint 1 OUT Descriptor
USB_ENDPOINT_DESCSIZE,// bLength
USB_ENDPOINT_DESCRIPTOR,// bDescriptorType
0x01,// bEndpointAddress
USB_EPTYPE_INTR,// bAttrib
HID_PACKET_SIZE,// wMaxPacketSize (LSB)
0x00,// wMaxPacketSize (MSB)
5,// bInterval
};
#define LANG_STRING htole16( SLAB_USB_LANGUAGE )
#define MFR_STRING 'S','i','l','i','c','o','n',' ','L','a','b','s','\0'
#define MFR_SIZE 13
#define PROD_STRING 'E','O','S',' ','W','a','l','l','e','t','\0'
#define PROD_SIZE 11
#define SER_STRING '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','\0'
#define SER_SIZE 17
#define CFG_STRING 'C','o','n','f','i','g',' ','#','1','\0'
#define CFG_SIZE 10
#define INT0_STRING 'E','O','S',' ','W','a','l','l','e','t','\0'
#define INT0_SIZE 11
LANGID_STATIC_CONST_STRING_DESC( langDesc[], LANG_STRING );
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( mfrDesc[], MFR_STRING, MFR_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( prodDesc[], PROD_STRING, PROD_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( serDesc[], SER_STRING, SER_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( cfgDesc[], CFG_STRING, CFG_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( int0Desc[], INT0_STRING, INT0_SIZE);
//-----------------------------------------------------------------------------
SI_SEGMENT_POINTER(myUsbStringTable_USEnglish[],
static const USB_StringDescriptor_TypeDef,
const SI_SEG_CODE) =
{
langDesc,
mfrDesc,
prodDesc,
serDesc,
int0Desc,
};
//-----------------------------------------------------------------------------
SI_SEGMENT_VARIABLE(initstruct,
const USBD_Init_TypeDef,
SI_SEG_CODE) =
{
deviceDesc, // deviceDescriptor
configDesc,// configDescriptor
myUsbStringTable_USEnglish,// stringDescriptors
sizeof(myUsbStringTable_USEnglish) / sizeof(void *)// numberOfStrings
};
#ifdef __cplusplus
}
#endif

17
efm8/src/main.c Normal file
View File

@@ -0,0 +1,17 @@
#include <SI_EFM8UB1_Register_Enums.h>
#include "InitDevice.h"
#include "efm8_usb.h"
#include "printing.h"
int main(void) {
enter_DefaultMode_from_RESET();
cprints("hello,world\r\n");
while (1) {
}
}

171
efm8/src/printing.c Normal file
View File

@@ -0,0 +1,171 @@
/*
* printing.c
*
* Created on: Jun 25, 2018
* Author: conor
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdarg.h>
#include <stdio.h>
#include "printing.h"
void putf(char c)
{
uint8_t i;
SBUF0 = c;
// Blocking delay that works for 115200 baud on this device (<1ms)
for (i=0; i<200; i++){}
for (i=0; i<200; i++){}
for (i=0; i<190; i++){}
watchdog();
}
void dump_hex(uint8_t* hex, uint8_t len)
{
uint8_t i;
for (i=0 ; i < len ; i++)
{
if (hex[i]<0x10)
{
putf('0');
}
cputb(hex[i]);
}
cprints("\r\n");
}
void cprints(char* d)
{
while(*d)
{
// UART0 output queue
putf(*d++);
}
}
static void int2str_reduce_n(char ** snum, uint32_t copy, uint8_t n)
{
do
{
copy /= n;
}while(copy);
}
static const char * __digits = "0123456789abcdef";
static char xdata __int2str_buf[9];
static void int2str_map_n(char ** snum, uint32_t i, uint8_t n)
{
do
{
*--*snum = __digits[i % n];
i /= n;
}while(i);
}
#define dint2str(i) __int2strn(i,10)
#define xint2str(i) __int2strn(i,16)
char * __int2strn(int32_t i, uint8_t n)
{
char * snum = __int2str_buf;
if (i<0) *snum++ = '-';
int2str_reduce_n(&snum, i, n);
*snum = '\0';
int2str_map_n(&snum, i, n);
return snum;
}
void cputd(int32_t i)
{
cprints(dint2str((int32_t)i));
}
void cputx(int32_t i)
{
cprints(xint2str(i));
}
static void put_space()
{
cprints(" ");
}
static void put_line()
{
cprints("\r\n");
}
void cprintd(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputd((int32_t)va_arg(args, int16_t));
}
put_line();
va_end(args);
}
void cprintl(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputl(va_arg(args, int32_t));
cprints(" ");
}
put_line();
va_end(args);
}
void cprintx(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputx((int32_t)va_arg(args, uint16_t));
cprints(" ");
}
put_line();
va_end(args);
}
void cprintb(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputb(va_arg(args, uint8_t));
put_space();
}
put_line();
va_end(args);
}
void cprintlx(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputlx(va_arg(args, int32_t));
put_space();
}
put_line();
va_end(args);
}