Skip to content

Commit

Permalink
Increased clock to 96Mhz and implemented initial usb_init routine
Browse files Browse the repository at this point in the history
The clock setup should be moved into sysinit
  • Loading branch information
kcuzner committed Nov 30, 2014
1 parent c788925 commit 8578c7a
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 8 deletions.
5 changes: 4 additions & 1 deletion scope-teensy/include/arm_cm4.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
#define ARM_INTERRUPT_LEVEL_BITS 4

/*Determines the correct IRQ number from a INT value */
#define IRQ(N) (N - (1 << ARM_INTERRUPT_LEVEL_BITS))
#define IRQ(N) (N - (1 << ARM_INTERRUPT_LEVEL_BITS))

/*Sets the priority of an interrupt*/
#define NVIC_SET_PRIORITY(irqnum, priority) (*((volatile uint8_t *)0xE000E400 + (irqnum)) = (uint8_t)(priority))

/***********************************************************************/
// function prototypes for arm_cm4.c
Expand Down
4 changes: 2 additions & 2 deletions scope-teensy/include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
* 72 MHz 8 36
*
*/
#define PRDIV_VAL 8 /* PLL prescaler */
#define VDIV_VAL 36 /* PLL multiplier */
#define PRDIV_VAL 4 /* PLL prescaler */
#define VDIV_VAL 24 /* PLL multiplier */

/*
* Optionally define the system console (one of the UARTs) for serial I/O.
Expand Down
19 changes: 19 additions & 0 deletions scope-teensy/include/usb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Header file for my implementation of using the USB peripheral
* Kevin Cuzner
*/
#ifndef _USB_H_
#define _USB_H_

/**
* Number of USB endpoints
* 15 max
*/
#define USB_N_ENDPOINTS 0

/**
* Initializes the USB module
*/
void usb_init(void);

#endif // _USB_H_
12 changes: 7 additions & 5 deletions scope-teensy/src/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "common.h"
#include "arm_cm4.h"
#include "adc.h"
#include "usb.h"

#define LED_ON GPIOC_PSOR=(1<<5)
#define LED_OFF GPIOC_PCOR=(1<<5)
Expand Down Expand Up @@ -38,15 +39,16 @@ int main(void)
PIT_TCTRL1 |= PIT_TCTRL_TEN_MASK; // start Timer 1

adc_init(8);
usb_init();

enable_irq(IRQ(INT_PIT1));
EnableInterrupts

while(1)
{
LED_ON;
LED2_ON;
for (n = 0; n < s; n++);
LED_OFF;
LED2_OFF;
for (n = 0; n < s; n++);
}

Expand All @@ -60,10 +62,10 @@ void PIT1_IRQHandler()
static uint8_t stat = 0;
if (count == 30)
{
if (stat)
LED2_ON;
/*if (stat)
LED_ON;
if (!stat)
LED2_OFF;
LED_OFF;*/
stat ^= 0x01;
count = 0;
}
Expand Down
101 changes: 101 additions & 0 deletions scope-teensy/src/usb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "usb.h"
#include "arm_cm4.h"

/**
* Descriptor bits struct
* See Table 41-4
*/
typedef struct {
unsigned rsrv0 :6; //31-26
unsigned bc :10; //25-16
unsigned rsrv1 :8; //15-8
unsigned own :1; //7
unsigned data0 :1; //6
union { //5-2
unsigned tok_pid :4;
struct {
unsigned keep :1;
unsigned ninc :1;
unsigned dts :1;
unsigned bdt_stall :1;
};
};
unsigned rsrv2 :2; //1-0
} bdt_bits_t;

/**
* Buffer Descriptor Table entry
* There are two entries per direction per endpoint:
* In Even/Odd
* Out Even/Odd
* A bidirectional endpoint would then need 4 entries
*/
typedef struct {
union {
uint32_t desc;
bdt_bits_t desc_bits;
};
void* addr;
} bdt_t;

// we enforce a max of 15 endpoints (15 + 1 control = 16)
#if USB_N_ENDPOINTS > 15
#error Maximum USB endpoints must be <=15
#endif // USB_N_ENDPOINTS

/**
* Buffer descriptor table, aligned to a 512-byte boundary (see linker file)
*/
__attribute__ ((section(".usbdescriptortable"), used))
static bdt_t table[(USB_N_ENDPOINTS + 1)*4]; //max endpoints is 15 + 1 control

void usb_init(void)
{
uint32_t i;

//reset the buffer descriptors
for (i = 0; i < (USB_N_ENDPOINTS + 1) * 4; i++)
{
table[i].desc = 0;
table[i].addr = 0;
}

//1: Select clock source
SIM_SOPT2 |= SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK; //we use MCGPLLCLK divided by USB fractional divider
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1);// SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC_MASK; //(USBFRAC + 1)/(USBDIV + 1) = (1 + 1)/(2 + 1) = 2/3 for 72Mhz clock

//2: Gate USB clock
SIM_SCGC4 |= SIM_SCGC4_USBOTG_MASK;

//3: Software USB module reset
USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
while (USB0_USBTRC0 & USB_USBTRC0_USBRESET_MASK);

//4: Set BDT base registers
USB0_BDTPAGE1 = ((uint32_t)table) >> 8; //bits 15-9
USB0_BDTPAGE2 = ((uint32_t)table) >> 16; //bits 23-16
USB0_BDTPAGE3 = ((uint32_t)table) >> 24; //bits 31-24

//5: Clear all ISR flags and enable weak pull downs
USB0_ISTAT = 0xFF;
USB0_ERRSTAT = 0xFF;
USB0_OTGISTAT = 0xFF;
USB0_USBTRC0 |= 0x40; //a hint was given that this is an undocumented interrupt bit

//6: Enable USB reset interrupt
USB0_CTL = USB_CTL_USBENSOFEN_MASK;
USB0_USBCTRL = 0;

USB0_INTEN |= USB_INTEN_USBRSTEN_MASK;
//NVIC_SET_PRIORITY(IRQ(INT_USB0), 112);
enable_irq(IRQ(INT_USB0));

//7: Enable pull-up resistor on D+ (Full speed, 12Mbit/s)
USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;
}

void USBOTG_IRQHandler(void)
{
USB0_ISTAT = USB0_ISTAT;
GPIOC_PSOR=(1<<5);
}

0 comments on commit 8578c7a

Please sign in to comment.