diff --git a/firmware/src/ssp.c b/firmware/src/ssp.c new file mode 100644 index 0000000..e9f6737 --- /dev/null +++ b/firmware/src/ssp.c @@ -0,0 +1,131 @@ +#include "LPC13xx.h" +#include "ssp.h" + +void SSPSend( char *buf, uint32_t Length ) +{ + uint32_t i; + uint8_t Dummy = Dummy; + + for ( i = 0; i < Length; i++ ) + { + /* Move on only if NOT busy and TX FIFO not full. */ + while ( (LPC_SSP->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF ); + LPC_SSP->DR = *buf; + buf++; +#if !LOOPBACK_MODE + while ( (LPC_SSP->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE ); + /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO + on MISO. Otherwise, when SSP0Receive() is called, previous data byte + is left in the FIFO. */ + Dummy = LPC_SSP->DR; +#else + /* Wait until the Busy bit is cleared. */ + while ( LPC_SSP->SR & SSPSR_BSY ); +#endif + } + return; +} + +void SSPInit() { +// reset peripherals +LPC_SYSCON->PRESETCTRL |= (0x01<<0); // SSP reset de-asserted +LPC_SYSCON->SYSAHBCLKCTRL |= (0x01<<11); // Enables clock for SSP. +LPC_SYSCON->SSPCLKDIV = 2; // div clock by 2 + +LPC_IOCON->PIO0_8 &= ~0x07; // ??? +LPC_IOCON->PIO0_8 |= 0x01; // MISO + +LPC_IOCON->PIO0_9 &= ~0x07; // ??? +LPC_IOCON->PIO0_9 |= 0x01; // MOSI + +#ifdef __JTAG_DISABLED +LPC_IOCON->SCKLOC = 0x00; +LPC_IOCON->SWCLK_PIO0_10 &= ~0x07; +LPC_IOCON->SWCLK_PIO0_10 |= 0x02;>/* SSP CLK */ +#endif + +// This register is used to select a pin among three possible choices for the SSP SCK function. +LPC_IOCON->SCKLOC = 1; // Selects SCK function for pin PIO2_11/SCK +LPC_IOCON->PIO2_11 = 1; + +// set SSEL as GPIO that the master has total control of the sequence +LPC_IOCON->PIO0_2 &= ~0x07; +LPC_IOCON->PIO0_2 |= 0x01; + +// TODO ????????????????????????????????? +LPC_SSP->CR0 = 0x0007; +LPC_SSP->CPSR = 0x02; + + + +LPC_IOCON->PIO0_7 = 0x00; // D/C^ +LPC_GPIO0->DIR |= 1 << 7; + +LPC_IOCON->PIO2_0 = 0x00; // RES^ +LPC_GPIO2->DIR |= 1 << 0; + + +// SSP Enable with Master mode +LPC_SSP->CR1 = (0x01<<1) | (0x00<<2); + +NVIC_EnableIRQ(SSP_IRQn); + +/* Set SSPINMS registers to enable interrupts */ +/* enable all error related interrupts */ +LPC_SSP->IMSC = (0x1<<0) | (0x1<<1); + +int i; +// reset +//LPC_GPIO2->MASKED_ACCESS[0x01<<0] = 1 << 0; +// for (i = 0; i < 100; i++); +//LPC_GPIO2->MASKED_ACCESS[0x01<<0] = 0 << 0; + +// select +//LPC_GPIO0->MASKED_ACCESS[0x01<<2] = 0 << 2; +// for (i = 0; i < 100; i++); + +// command +LPC_GPIO0->MASKED_ACCESS[0x01<<7] = 0 << 7; +// for (i = 0; i < 100; i++); +/* +SSPSend("\x21\xc8\x06\x13\x20\x0c", 6); +// x:0 y:0 +SSPSend("\x20\x0c", 2); +SSPSend("\x80\x40", 2); + +// data +LPC_GPIO0->MASKED_ACCESS[0x01<<7] = 0 << 7; +// for (i = 0; i < 100; i++); + +SSPSend("\x21\xc8\x06\x13\x20\x0c", 6); + // x:0 y:0 +SSPSend("\x20\x0c", 2); + + +LPC_GPIO0->MASKED_ACCESS[0x01<<7] = 0 << 7; +*/ + SSPSend("\x21\xc8\x06\x13\x20\x0c", 6); + SSPSend("\x80\x40", 2); + //SSPSend("\x20\x0c", 2); + + +LPC_GPIO0->MASKED_ACCESS[0x01<<7] = 1 << 7; + + for (i=0;i<84*48;i++) + SSPSend("\x00", 1); + + SSPSend("\x00", 1); + SSPSend("\x00", 1); + +while (1){ + SSPSend("\x7f\x49\x49\x49\x36\x00", 6); // B + SSPSend("\x7f\x09\x19\x29\x46\x00", 6); // R + SSPSend("\x7f\x02\x0c\x02\x7f\x00", 6); // M + SSPSend("\x7f\x40\x40\x40\x40\x00", 6); // L + SSPSend("\x7e\x11\x11\x11\x7e\x00", 6); // A + SSPSend("\x7f\x49\x49\x49\x36\x00", 6); // B + SSPSend("\x00\x00\x00\x00\x00\x00\x00", 7); + for(i=0;i<100000;i++); +} + +} diff --git a/firmware/src/ssp.h b/firmware/src/ssp.h new file mode 100644 index 0000000..5262a92 --- /dev/null +++ b/firmware/src/ssp.h @@ -0,0 +1,118 @@ +/**************************************************************************** + * $Id:: ssp.h 3632 2010-06-01 22:54:42Z usb00423 $ + * Project: NXP LPC13xx SSP example + * + * Description: + * This file contains SSP code header definition. + * + **************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. +****************************************************************************/ +#ifndef __SSP_H__ +#define __SSP_H__ + +/* There are there modes in SSP: loopback, master or slave. */ +/* Here are the combination of all the tests. +(1) LOOPBACK test: LOOPBACK_MODE=1, TX_RX_ONLY=0, USE_CS=1; +(2) Serial EEPROM test: LOOPBACK_MODE=0, TX_RX_ONLY=0, USE_CS=0; (default) +(3) TX(Master) Only: LOOPBACK_MODE=0, SSP_SLAVE=0, TX_RX_ONLY=1, USE_CS=1; +(4) RX(Slave) Only: LOOPBACK_MODE=0, SSP_SLAVE=1, TX_RX_ONLY=0, USE_CS=1 */ + +#define LOOPBACK_MODE 0 /* 1 is loopback, 0 is normal operation. */ +#define SSP_SLAVE 0 /* 1 is SLAVE mode, 0 is master mode */ +#define TX_RX_ONLY 0 /* 1 is TX or RX only depending on SSP_SLAVE + flag, 0 is either loopback mode or communicate + with a serial EEPROM. */ + +/* if USE_CS is zero, set SSEL as GPIO that you have total control of the sequence */ +/* When test serial SEEPROM(LOOPBACK_MODE=0, TX_RX_ONLY=0), set USE_CS to 0. */ +/* When LOOPBACK_MODE=1 or TX_RX_ONLY=1, set USE_CS to 1. */ + +#define USE_CS 0 +#define SSP_DEBUG 0 + +/* SPI read and write buffer size */ +#define SSP_BUFSIZE 16 +#define FIFOSIZE 8 + +#define DELAY_COUNT 10 +#define MAX_TIMEOUT 0xFF + +/* Port0.2 is the SSP select pin */ +#define SSP0_SEL (0x1<<2) + +/* SSP Status register */ +#define SSPSR_TFE (0x1<<0) +#define SSPSR_TNF (0x1<<1) +#define SSPSR_RNE (0x1<<2) +#define SSPSR_RFF (0x1<<3) +#define SSPSR_BSY (0x1<<4) + +/* SSP CR0 register */ +#define SSPCR0_DSS (0x1<<0) +#define SSPCR0_FRF (0x1<<4) +#define SSPCR0_SPO (0x1<<6) +#define SSPCR0_SPH (0x1<<7) +#define SSPCR0_SCR (0x1<<8) + +/* SSP CR1 register */ +#define SSPCR1_LBM (0x1<<0) +#define SSPCR1_SSE (0x1<<1) +#define SSPCR1_MS (0x1<<2) +#define SSPCR1_SOD (0x1<<3) + +/* SSP Interrupt Mask Set/Clear register */ +#define SSPIMSC_RORIM (0x1<<0) +#define SSPIMSC_RTIM (0x1<<1) +#define SSPIMSC_RXIM (0x1<<2) +#define SSPIMSC_TXIM (0x1<<3) + +/* SSP0 Interrupt Status register */ +#define SSPRIS_RORRIS (0x1<<0) +#define SSPRIS_RTRIS (0x1<<1) +#define SSPRIS_RXRIS (0x1<<2) +#define SSPRIS_TXRIS (0x1<<3) + +/* SSP0 Masked Interrupt register */ +#define SSPMIS_RORMIS (0x1<<0) +#define SSPMIS_RTMIS (0x1<<1) +#define SSPMIS_RXMIS (0x1<<2) +#define SSPMIS_TXMIS (0x1<<3) + +/* SSP0 Interrupt clear register */ +#define SSPICR_RORIC (0x1<<0) +#define SSPICR_RTIC (0x1<<1) + +/* ATMEL SEEPROM command set */ +#define WREN 0x06 /* MSB A8 is set to 0, simplifying test */ +#define WRDI 0x04 +#define RDSR 0x05 +#define WRSR 0x01 +#define READ 0x03 +#define WRITE 0x02 + +/* RDSR status bit definition */ +#define RDSR_RDY 0x01 +#define RDSR_WEN 0x02 + +/* If RX_INTERRUPT is enabled, the SSP RX will be handled in the ISR +SSPReceive() will not be needed. */ +extern void SSP_IRQHandler (void); +extern void SSPInit( void ); +extern void SSPSend( char *Buf, uint32_t Length ); +extern void SSPReceive( uint8_t *buf, uint32_t Length ); + +#endif /* __SSP_H__ */ +/***************************************************************************** +** End Of File +******************************************************************************/ + diff --git a/firmware/src/usbhidrom_main.c b/firmware/src/usbhidrom_main.c index f7eec7e..0f6ec10 100644 --- a/firmware/src/usbhidrom_main.c +++ b/firmware/src/usbhidrom_main.c @@ -21,6 +21,7 @@ #include "gpio.h" #include "rom_drivers.h" #include "config.h" +#include "ssp.h" #include @@ -64,10 +65,14 @@ int main (void) volatile int n; // Code Red Red Suite and LPCXpresso by Code Red both call SystemInit() in // the C startup code -#ifndef __CODERED__ +//#ifndef __CODERED__ SystemInit(); -#endif - +//#endif + +/* + LPC_GPIO2->MASKED_ACCESS[0x01<<0] = 1 << 0; + SSPSend("BIITER", 6); +*/ HidDevInfo.idVendor = USB_VENDOR_ID; HidDevInfo.idProduct = USB_PROD_ID; @@ -86,7 +91,7 @@ int main (void) LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG); /* Use pll and pin init function in rom */ - (*rom)->pUSBD->init_clk_pins(); + (*rom)->pUSBD->init_clk_pins(); /* insert a delay between clk init and usb init */ for (n = 0; n < 75; n++) {} @@ -94,6 +99,8 @@ int main (void) (*rom)->pUSBD->init(&DeviceInfo); /* USB Initialization */ (*rom)->pUSBD->connect(TRUE); /* USB Connect */ + SSPInit(); + while (1) __WFI(); } @@ -106,3 +113,10 @@ void USB_IRQHandler() { (*rom)->pUSBD->isr(); } + +void SSP_IRQHandler(void) +{ + while(1) + { + } +} diff --git a/firmware/test.c b/firmware/test.c index 3476af5..e1970f7 100644 --- a/firmware/test.c +++ b/firmware/test.c @@ -31,7 +31,7 @@ static const int PRODUCT_ID = 0x1337; // Values for bmRequestType in the Setup transaction's Data packet. static const int INSIZE = 64; -static const int OUTSIZE = 2; +static const int OUTSIZE = 64; static const int INTERFACE_NUMBER = 0; // Uses interrupt endpoint 1 IN and OUT: