efm8 usb bridge working

This commit is contained in:
Conor Patrick
2018-07-04 12:48:18 -04:00
parent ca882dc38a
commit 344a104ece
39 changed files with 9027 additions and 812 deletions

View File

@@ -29,8 +29,8 @@ extern void enter_DefaultMode_from_RESET(void) {
WDT_0_enter_DefaultMode_from_RESET();
PORTS_0_enter_DefaultMode_from_RESET();
PORTS_1_enter_DefaultMode_from_RESET();
PORTS_2_enter_DefaultMode_from_RESET();
PBCFG_0_enter_DefaultMode_from_RESET();
LFOSC_0_enter_DefaultMode_from_RESET();
CIP51_0_enter_DefaultMode_from_RESET();
CLOCK_0_enter_DefaultMode_from_RESET();
TIMER01_0_enter_DefaultMode_from_RESET();
@@ -184,14 +184,14 @@ extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void) {
- System clock divided by 4
- 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 2 low byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 3 high byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 3 low byte uses the system clock
- Timer 3 low byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 1 uses the system clock
***********************************************************************/
CKCON0 = CKCON0_SCA__SYSCLK_DIV_4 | CKCON0_T0M__PRESCALE
| CKCON0_T2MH__EXTERNAL_CLOCK | CKCON0_T2ML__SYSCLK
| CKCON0_T3MH__EXTERNAL_CLOCK | CKCON0_T3ML__SYSCLK
| CKCON0_T2MH__EXTERNAL_CLOCK | CKCON0_T2ML__EXTERNAL_CLOCK
| CKCON0_T3MH__EXTERNAL_CLOCK | CKCON0_T3ML__EXTERNAL_CLOCK
| CKCON0_T1M__SYSCLK;
// [CKCON0 - Clock Control 0]$
@@ -288,23 +288,19 @@ extern void TIMER16_2_enter_DefaultMode_from_RESET(void) {
// $[TMR2RLH - Timer 2 Reload High Byte]
/***********************************************************************
- Timer 2 Reload High Byte = 0x44
- Timer 2 Reload High Byte = 0x63
***********************************************************************/
TMR2RLH = (0x44 << TMR2RLH_TMR2RLH__SHIFT);
TMR2RLH = (0x63 << TMR2RLH_TMR2RLH__SHIFT);
// [TMR2RLH - Timer 2 Reload High Byte]$
// $[TMR2RLL - Timer 2 Reload Low Byte]
/***********************************************************************
- Timer 2 Reload Low Byte = 0x80
- Timer 2 Reload Low Byte = 0xC0
***********************************************************************/
TMR2RLL = (0x80 << TMR2RLL_TMR2RLL__SHIFT);
TMR2RLL = (0xC0 << TMR2RLL_TMR2RLL__SHIFT);
// [TMR2RLL - Timer 2 Reload Low Byte]$
// $[TMR2CN0]
/***********************************************************************
- Start Timer 2 running
***********************************************************************/
TMR2CN0 |= TMR2CN0_TR2__RUN;
// [TMR2CN0]$
// $[Timer Restoration]
@@ -327,6 +323,10 @@ extern void TIMER16_3_enter_DefaultMode_from_RESET(void) {
// [TMR3CN1 - Timer 3 Control 1]$
// $[TMR3CN0 - Timer 3 Control]
/***********************************************************************
- Timer 3 clock is the low-frequency oscillator divided by 8
***********************************************************************/
TMR3CN0 |= TMR3CN0_T3XCLK__LFOSC_DIV_8;
// [TMR3CN0 - Timer 3 Control]$
// $[TMR3H - Timer 3 High Byte]
@@ -342,6 +342,10 @@ extern void TIMER16_3_enter_DefaultMode_from_RESET(void) {
// [TMR3RLL - Timer 3 Reload Low Byte]$
// $[TMR3CN0]
/***********************************************************************
- Start Timer 3 running
***********************************************************************/
TMR3CN0 |= TMR3CN0_TR3__RUN;
// [TMR3CN0]$
// $[Timer Restoration]
@@ -408,7 +412,7 @@ extern void PORTS_1_enter_DefaultMode_from_RESET(void) {
// $[P1MDOUT - Port 1 Output Mode]
/***********************************************************************
- P1.0 output is open-drain
- P1.1 output is open-drain
- P1.1 output is push-pull
- P1.2 output is open-drain
- P1.3 output is open-drain
- P1.4 output is push-pull
@@ -416,7 +420,7 @@ extern void PORTS_1_enter_DefaultMode_from_RESET(void) {
- P1.6 output is push-pull
- P1.7 output is open-drain
***********************************************************************/
P1MDOUT = P1MDOUT_B0__OPEN_DRAIN | P1MDOUT_B1__OPEN_DRAIN
P1MDOUT = P1MDOUT_B0__OPEN_DRAIN | P1MDOUT_B1__PUSH_PULL
| P1MDOUT_B2__OPEN_DRAIN | P1MDOUT_B3__OPEN_DRAIN
| P1MDOUT_B4__PUSH_PULL | P1MDOUT_B5__PUSH_PULL
| P1MDOUT_B6__PUSH_PULL | P1MDOUT_B7__OPEN_DRAIN;
@@ -520,9 +524,9 @@ extern void UART_0_enter_DefaultMode_from_RESET(void) {
extern void SPI_0_enter_DefaultMode_from_RESET(void) {
// $[SPI0CKR - SPI0 Clock Rate]
/***********************************************************************
- SPI0 Clock Rate = 0x17
- SPI0 Clock Rate = 0x0B
***********************************************************************/
SPI0CKR = (0x17 << SPI0CKR_SPI0CKR__SHIFT);
SPI0CKR = (0x0B << SPI0CKR_SPI0CKR__SHIFT);
// [SPI0CKR - SPI0 Clock Rate]$
// $[SPI0FCN0 - SPI0 FIFO Control 0]
@@ -545,3 +549,20 @@ extern void SPI_0_enter_DefaultMode_from_RESET(void) {
}
extern void LFOSC_0_enter_DefaultMode_from_RESET(void) {
// $[LFO0CN - Low Frequency Oscillator Control]
/***********************************************************************
- Internal L-F Oscillator Enabled
- Divide by 8 selected
***********************************************************************/
LFO0CN &= ~LFO0CN_OSCLD__FMASK;
LFO0CN |= LFO0CN_OSCLEN__ENABLED;
// [LFO0CN - Low Frequency Oscillator Control]$
// $[Wait for LFOSC Ready]
while ((LFO0CN & LFO0CN_OSCLRDY__BMASK) != LFO0CN_OSCLRDY__SET)
;
// [Wait for LFOSC Ready]$
}

View File

@@ -38,6 +38,7 @@ uint8_t tmpBuffer;
void USBD_ResetCb(void) {
// cprints("USBD_ResetCb\r\n");
// u2f_print_ev("USBD_ResetCb\r\n");
}
@@ -45,6 +46,7 @@ void USBD_ResetCb(void) {
void USBD_DeviceStateChangeCb(USBD_State_TypeDef oldState,
USBD_State_TypeDef newState) {
// cprints("USBD_DeviceStateChangeCb\r\n");
UNUSED(oldState);
UNUSED(newState);
@@ -52,6 +54,7 @@ void USBD_DeviceStateChangeCb(USBD_State_TypeDef oldState,
}
bool USBD_IsSelfPoweredCb(void) {
// cprints("USBD_IsSelfPoweredCb\r\n");
return false;
}
@@ -60,19 +63,22 @@ USB_Status_TypeDef USBD_SetupCmdCb(
SI_VARIABLE_SEGMENT_POINTER(setup, USB_Setup_TypeDef, MEM_MODEL_SEG)) {
USB_Status_TypeDef retVal = USB_STATUS_REQ_UNHANDLED;
// USB_Status_TypeDef retVal = USB_STATUS_OK;
// cprints("USBD_SetupCmdCb\r\n");
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.
// cprints("USB_SETUP_TYPE_STANDARD\r\n");
switch (setup->bRequest) {
case GET_DESCRIPTOR:
// cprints("GET_DESCRIPTOR\r\n");
if (setup->wIndex == 0)
{
if ((setup->wValue >> 8) == USB_HID_REPORT_DESCRIPTOR) {
// cprints("1\r\n");
USBD_Write(EP0, ReportDescriptor0,
EFM8_MIN(sizeof(ReportDescriptor0), setup->wLength),
@@ -80,7 +86,7 @@ USB_Status_TypeDef USBD_SetupCmdCb(
retVal = USB_STATUS_OK;
} else if ((setup->wValue >> 8) == USB_HID_DESCRIPTOR) {
// cprints("2\r\n");
USBD_Write(EP0, (&configDesc[18]),
EFM8_MIN(USB_HID_DESCSIZE, setup->wLength), false);
retVal = USB_STATUS_OK;
@@ -94,10 +100,12 @@ USB_Status_TypeDef USBD_SetupCmdCb(
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)
&& (setup->wIndex == HID_INTERFACE_INDEX))
{
// cprints("USB_SETUP_TYPE_CLASS\r\n");
// Implement the necessary HID class specific commands.
switch (setup->bRequest)
{
case USB_HID_SET_IDLE:
// cprints("USB_HID_SET_IDLE\r\n");
if (((setup->wValue & 0xFF) == 0) // Report ID
&& (setup->wLength == 0)
&& (setup->bmRequestType.Direction != USB_SETUP_DIR_IN))
@@ -107,6 +115,7 @@ USB_Status_TypeDef USBD_SetupCmdCb(
break;
case USB_HID_GET_IDLE:
// cprints("USB_HID_GET_IDLE\r\n");
if ((setup->wValue == 0) // Report ID
&& (setup->wLength == 1)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN))
@@ -120,6 +129,10 @@ USB_Status_TypeDef USBD_SetupCmdCb(
break;
}
}
else
{
// cprints("nothing\r\n");
}
return retVal;
}

79
efm8/src/eeprom.c Normal file
View File

@@ -0,0 +1,79 @@
#include <SI_EFM8UB1_Register_Enums.h>
#include <stdint.h>
#include "eeprom.h"
#include "printing.h"
char __erase_mem[3];
static void erase_ram()
{
data uint16_t i;
data uint8_t xdata * clear = 0;
for (i=0; i<0x400;i++)
{
*(clear++) = 0x0;
}
}
void eeprom_init()
{
uint8_t secbyte;
eeprom_read(0xFBFF,&secbyte,1);
if (secbyte == 0xff)
{
eeprom_erase(0xFBC0);
secbyte = -32;
eeprom_write(0xFBFF, &secbyte, 1);
erase_ram();
// Reboot
cprints("rebooting\r\n");
RSTSRC = (1<<4);
}
else
{
// cprints("no reboot\r\n");
}
}
void eeprom_read(uint16_t addr, uint8_t * buf, uint8_t len)
{
uint8_t code * eepaddr = (uint8_t code *) addr;
bit old_int;
while(len--)
{
old_int = IE_EA;
IE_EA = 0;
*buf++ = *eepaddr++;
IE_EA = old_int;
}
}
void _eeprom_write(uint16_t addr, uint8_t * buf, uint8_t len, uint8_t flags)
{
uint8_t xdata * data eepaddr = (uint8_t xdata *) addr;
bit old_int;
while(len--)
{
old_int = IE_EA;
IE_EA = 0;
// Enable VDD monitor
VDM0CN = 0x80;
RSTSRC = 0x02;
// unlock key
FLKEY = 0xA5;
FLKEY = 0xF1;
PSCTL |= flags;
*eepaddr = *buf;
PSCTL &= ~flags;
IE_EA = old_int;
eepaddr++;
buf++;
}
}

View File

@@ -4,13 +4,16 @@
#include "uart_1.h"
#include "printing.h"
#define BUFFER_SIZE 10
#define BUFFER_SIZE 13
uint8_t write_ptr = 0;
uint8_t read_ptr = 0;
uint8_t count = 0;
data uint8_t write_ptr = 0;
data uint8_t read_ptr = 0;
data uint8_t i_ptr = 0;
data uint8_t count = 0;
data uint8_t writebackbuf_count = 0;
uint8_t hidmsgbuf[64][BUFFER_SIZE];
data uint8_t writebackbuf[64];
void usb_transfer_complete()
{
@@ -20,81 +23,129 @@ void usb_transfer_complete()
{
write_ptr = 0;
}
cprints("read hid msg\r\n");
if (count == 1 && i_ptr == 0)
{
SPI0DAT = hidmsgbuf[read_ptr][i_ptr++];
}
// MSG_RDY_INT_PIN = 0;
// MSG_RDY_INT_PIN = 1;
}
void spi_transfer_complete()
{
count--;
i_ptr = 0;
SPI0FCN0 |= (1<<2); // Flush rx fifo buffer
if (count)
{
SPI0DAT = hidmsgbuf[read_ptr][i_ptr++];
}
read_ptr++;
if (read_ptr == BUFFER_SIZE)
{
read_ptr = 0;
}
cprints("sent hid msg\r\n");
// cprints("sent hid msg\r\n");
}
SI_INTERRUPT (SPI0_ISR, SPI0_IRQn)
{
static unsigned char command;
static unsigned char array_index = 0;
static unsigned char state = 0;
char arr[2];
if (SPI0CN0_WCOL == 1)
{
// Write collision occurred
SPI0CN0_WCOL = 0; // Clear the Write collision flag
// Write collision occurred
SPI0CN0_WCOL = 0;
// cprints("SPI0CN0_WCOL\r\n");
}
else if(SPI0CN0_RXOVRN == 1)
{
// Receive overrun occurred
SPI0CN0_RXOVRN = 0; // Clear the Receive Overrun flag
// Receive overrun occurred
SPI0CN0_RXOVRN = 0;
// cprints("SPI0CN0_RXOVRN\r\n");
}
else
{
// SPI0CN0_SPIF caused the interrupt
if (EFM32_RW_PIN)
{
if (writebackbuf_count < 64) writebackbuf[writebackbuf_count++] = SPI0DAT;
else cprints("overflow\r\n");
}
else
{
if (count)
{
if (i_ptr < 64)
{
SPI0DAT = hidmsgbuf[read_ptr][i_ptr++];
arr[0] = SPI0DAT; // Read the command
arr[1] = 0;
cprints("got data: ");
cprints(arr);
cprints("\n\r");
SPI0CN0_SPIF = 0; // Clear the SPIF0 flag
}
else
{
spi_transfer_complete();
}
}
}
SPI0CN0_SPIF = 0;
}
}
void usb_write()
{
data uint8_t errors = 0;
while (USB_STATUS_OK != (USBD_Write(EP1IN, writebackbuf, 64, false)))
{
delay(2);
if (errors++ > 30)
{
cprints("ERROR USB WRITE\r\n");
break;
}
}
}
int main(void) {
volatile int xdata i,j,k;
uint8_t k;
uint16_t t1 = 0;
uint8_t lastcount = count;
int reset;
data int lastwritecount = writebackbuf_count;
enter_DefaultMode_from_RESET();
IE_EA = 1;
eeprom_init();
SCON0_TI = 1;
P2_B0 = 1;
MSG_RDY_INT_PIN = 1;
// enable SPI interrupts
SPI0FCN1 = SPI0FCN1 | (1<<4);
IE_EA = 1;
IE_ESPI0 = 1;
cprints("hello,world\r\n");
reset = RSTSRC;
cprintx("reset source: ", 1, reset);
while (1) {
k++;
for (i = 0; i < 1000; i++)
// delay(1500);
if (millis() - t1 > 1500)
{
for (j = 0; j < 100; j++)
{
}
P1_B4 = i&1;
P1_B5 = k++&1;
t1 = millis();
}
P1_B5 = k&1;
if (!USBD_EpIsBusy(EP1OUT) && !USBD_EpIsBusy(EP1IN))
{
// cprintd("sched read to ",1,reset);
if (count == BUFFER_SIZE)
{
cprints("Warning, USB buffer full\r\n");
@@ -104,9 +155,32 @@ int main(void) {
USBD_Read(EP1OUT, hidmsgbuf[write_ptr], 64, true);
}
}
if (count != lastcount)
if (writebackbuf_count == 64)
{
cprints("+1 to count \r\n");
// cprints("<< ");
// dump_hex(writebackbuf,64);
writebackbuf_count = 0;
// while (USBD_EpIsBusy(EP1IN))
// ;
usb_write();
}
if (lastcount != count)
{
if (count > lastcount)
{
// cprints(">> ");
// dump_hex(writebackbuf,64);
MSG_RDY_INT_PIN = 0;
MSG_RDY_INT_PIN = 1;
}
else
{
// cprints("efm32 read hid msg\r\n>> ");
// dump_hex(debug,64);
}
lastcount = count;
}

View File

@@ -11,6 +11,13 @@
#include <stdio.h>
#include "printing.h"
void delay(uint16_t ms)
{
uint16_t m1 = millis();
while (millis() - m1 < ms)
;
}
#ifdef USE_PRINTING
void putf(char c)
{
uint8_t i;
@@ -19,20 +26,23 @@ void putf(char c)
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;
uint8_t b;
const char lut[] = "0123456789abcdef";
for (i=0 ; i < len ; i++)
{
if (hex[i]<0x10)
{
putf('0');
}
cputb(hex[i]);
b = ((*hex) & 0xf0)>>4;
putf(lut[b]);
b = ((*hex) & 0x0f);
putf(lut[b]);
hex++;
}
cprints("\r\n");
}
@@ -169,3 +179,4 @@ void cprintlx(const char * tag, uint8_t c, ...)
put_line();
va_end(args);
}
#endif