From f7f7d63d8a83ec5a2313e21143ff73c247c389a5 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Tue, 11 Jun 2013 07:03:35 +0200 Subject: Current (broken) state of SPI/WM8723 code. --- firmware/drivers/cli.c | 130 ++++++++++++++++ firmware/drivers/cli.h | 33 ++++ firmware/drivers/led.c | 55 +++++++ firmware/drivers/led.h | 35 +++++ firmware/drivers/spi.c | 264 ++++++++++++++++++++++++++++++++ firmware/drivers/spi.h | 37 +++++ firmware/drivers/uart.c | 169 +++++++++++++++++++++ firmware/drivers/uart.h | 52 +++++++ firmware/drivers/wm8523.c | 111 +++++--------- firmware/drivers/wm8523.h | 8 +- firmware/lpc17xx/lpc17xx_pinsel.c | 308 ++++++++++++++++++++++++++++++++++++++ firmware/lpc17xx/lpc17xx_pinsel.h | 210 ++++++++++++++++++++++++++ firmware/lpc17xx/lpc17xx_spi.c | 3 + firmware/src/p2m.c | 30 ++-- firmware/src/uart.c | 169 --------------------- firmware/src/uart.h | 50 ------- 16 files changed, 1361 insertions(+), 303 deletions(-) create mode 100644 firmware/drivers/cli.c create mode 100644 firmware/drivers/cli.h create mode 100644 firmware/drivers/led.c create mode 100644 firmware/drivers/led.h create mode 100644 firmware/drivers/spi.c create mode 100644 firmware/drivers/spi.h create mode 100644 firmware/drivers/uart.c create mode 100644 firmware/drivers/uart.h create mode 100644 firmware/lpc17xx/lpc17xx_pinsel.c create mode 100644 firmware/lpc17xx/lpc17xx_pinsel.h delete mode 100644 firmware/src/uart.c delete mode 100644 firmware/src/uart.h diff --git a/firmware/drivers/cli.c b/firmware/drivers/cli.c new file mode 100644 index 0000000..33c350e --- /dev/null +++ b/firmware/drivers/cli.c @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * cli.c + * + * Thu Jun 6 20:20:20 CEST 2013 + * Copyright 2013 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "cli.h" + +#include +#include + +#include "uart.h" + +void cli_init() +{ + UARTInit(0, 115200); /* baud rate setting */ +} + +static int cli_strlen(char *p0) +{ + char *p = p0; + while(*p) p++; + return p0 - p; +} + +static inline void cli_write_int(int i) +{ + if(i < 0) { + UARTSend(0, "-", 1); + i *= -1; + } + + char buf[] = "\0\0"; + int pos = 1000000000; + int tvaersum = 0; + while(pos) { + int res = i / pos; + i -= res * pos; + + tvaersum += res; + if(tvaersum || pos == 1) { + buf[0] = res + '0'; + UARTSend(0, buf, 1); + } + pos /= 10; + } +} + +static inline char *cli_to_hex(char i) +{ + static const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + static char buf[] = { 'f', 'f', 0 }; + buf[0] = hex[i / 16]; + buf[1] = hex[i % 16]; + return buf; +} + +static int cli_write_format(const char *fmt, va_list ap) +{ + char buf[] = "\0\0"; + + const char *p = fmt; + while(*p) { + if(*p != '%') { + buf[0] = *p; + + UARTSend(0, buf, 1); + } else { + p++; + if(!*p) { + return 1; // Error: Invalid format string + } + if(*p == '\n') UARTSend(0, "\n\r", 2); + if(*p == '%') UARTSend(0, "%", 1); + if(*p == 'd') cli_write_int(va_arg(ap, int)); + if(*p == 'c') { + buf[0] = va_arg(ap, int); + UARTSend(0, buf, 1); + } + if(*p == 'x') { + char *c = va_arg(ap, char *); + size_t sz = va_arg(ap, int); + while(sz) { + UARTSend(0, cli_to_hex(*c), 2); + c++; sz--; + } + } + if(*p == 's') { + char *str = va_arg(ap, char *); + UARTSend(0, str, cli_strlen(str)); + } + } + p++; + } + + // If last character wasn't a newline, print one. + if(p > fmt && *(p - 1) != '\n') UARTSend(0, "\n\r", 2); + + return 0; +} + +int cli_write(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + cli_write_format(fmt, ap); + va_end(ap); + + return 0; +} diff --git a/firmware/drivers/cli.h b/firmware/drivers/cli.h new file mode 100644 index 0000000..ecc373b --- /dev/null +++ b/firmware/drivers/cli.h @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * cli.h + * + * Thu Jun 6 20:20:20 CEST 2013 + * Copyright 2013 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PEDAL2METAL_CLI_H__ +#define __PEDAL2METAL_CLI_H__ + +void cli_init(); +int cli_write(const char *fmt, ...); + +#endif/*__PEDAL2METAL_CLI_H__*/ diff --git a/firmware/drivers/led.c b/firmware/drivers/led.c new file mode 100644 index 0000000..fe8d6f5 --- /dev/null +++ b/firmware/drivers/led.c @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * led.c + * + * Sun Jun 9 12:51:55 CEST 2013 + * Copyright 2013 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "led.h" + +#include + +int led_state = 0; + +void LED_Init() +{ + LPC_SC->PCONP |= ( 1 << 15 ); // power up GPIO + LPC_GPIO1->FIODIR |= 1 << 29; // puts P1.29 into output mode. +} + +void LED_on() +{ + led_state = 1; + LPC_GPIO1->FIOPIN |= 1 << 29; // make P1.29 high +} + +void LED_off() +{ + led_state = 0; + LPC_GPIO1->FIOPIN &= ~( 1 << 29 ); // make P1.29 low +} + +void LED_toggle() +{ + if(led_state) LED_off(); + else LED_on(); +} diff --git a/firmware/drivers/led.h b/firmware/drivers/led.h new file mode 100644 index 0000000..2c81474 --- /dev/null +++ b/firmware/drivers/led.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * led.h + * + * Sun Jun 9 12:51:55 CEST 2013 + * Copyright 2013 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PEDAL2METAL_LED_H__ +#define __PEDAL2METAL_LED_H__ + +void LED_Init(); +void LED_on(); +void LED_off(); +void LED_toggle(); + +#endif/*__PEDAL2METAL_LED_H__*/ diff --git a/firmware/drivers/spi.c b/firmware/drivers/spi.c new file mode 100644 index 0000000..6209a03 --- /dev/null +++ b/firmware/drivers/spi.c @@ -0,0 +1,264 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * spi.c + * + * Sun Jun 9 14:02:49 CEST 2013 + * Copyright 2013 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "spi.h" + +#include + + +#define USE_CMSIS + +#ifdef USE_CMSIS +#include +#include + +LPC_SPI_TypeDef *spi; +#else/*USE_CMSIS*/ + +// SPI power bit in PCONP register (see table 46) +#define PCSPI_BIT 8 + +// SPI clock bits (16 and 17) in PCLKSEL0 register (see table 40) +#define PCLK_SPI_BIT 16 + +// Clock speed devisors. Values for PCLKSEL0 register (See table 42) +typedef enum { + CCLK_4 = 0x0, // 00: PCLK_peripheral = CCLK/4 + CCLK_1 = 0x1, // 01: PCLK_peripheral = CCLK + CCLK_2 = 0x2, // 10: PCLK_peripheral = CCLK/2 + CCLK_8 = 0x3, // 11: PCLK_peripheral = CCLK/8 +} ClockDevisor; + +// PINSEL0 function value for SCK0 function (see table 79) +#define SCK0_FUNCTION 0x2 +#define SCK0_BIT 30 + +// PINSEL1 function value for SSEL0 function (see table 80) +#define SSEL0_FUNCTION 0x2 +#define SSEL0_BIT 0 + +// PINSEL1 function value for MISO0 function (see table 80) +#define MISO0_FUNCTION 0x2 +#define MISO0_BIT 2 + +// PINSEL1 function value for MOSI0 function (see table 80) +#define MOSI0_FUNCTION 0x2 +#define MOSI0_BIT 4 + +#endif/*USE_CMSIS*/ + +/** + * Initialisation as described in "17.1 Basic Configuration" + */ +void spi_init() +{ +#ifdef USE_CMSIS + SPI_CFG_Type spi_cfg; + + // 16 bit data transfers + spi_cfg.Databit = SPI_DATABIT_8; + + // WM8523 samples bits on rising edges. Mode 0 or 3 will work + // http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase + + // Mode 0 + spi_cfg.CPHA = SPI_CPHA_FIRST; // 0 + spi_cfg.CPOL = SPI_CPOL_HI; // 0 + /* + // Mode 3 + spi_cfg.CPHA = SPI_CPHA_SECOND; // 1 + spi_cfg.CPOL = SPI_CPOL_LO; // 1 + */ + + // We are the master + spi_cfg.Mode = SPI_MASTER_MODE; + + // We run on a little endian mcu. + spi_cfg.DataOrder = SPI_DATA_MSB_FIRST; + + // Se WM8523 manual page 14. Min clock pulse width 40ns ~= 25MHz + spi_cfg.ClockRate = 1000;//1000000000; // 1MHz + + spi = LPC_SPI; + SPI_Init(spi, &spi_cfg); + + NVIC_EnableIRQ(SPI_IRQn); + +#else/*USE_CMSIS*/ + // Power up the SPI bus. + // Remark: On reset, the SPI is enabled (PCSPI = 1). + LPC_SC->PCONP |= (1 << PCSPI_BIT); // set bit 8 in PCONP (PCSPI bit) + + // Set clock speed (indirectly as clock devisor) + ClockDevisor clk = CCLK_8; + LPC_SC->PCLKSEL0 &= ~(0x3 << PCLK_SPI_BIT); + LPC_SC->PCLKSEL0 |= ((clk & 0x3) << PCLK_SPI_BIT); // set bit 16 and 17 in PCLKSEL0 + + // Make pin selection for SPI. + // SCK0: P1.20 + // SSEL0: P1.21 + // MOSI0: P1.23 + // MISO0: P1.24 + LPC_PINCON->PINSEL0 &= ~(0x3 << SCK0_BIT); + LPC_PINCON->PINSEL0 |= (SCK0_FUNCTION << SCK0_BIT); + + LPC_PINCON->PINSEL1 &= ~(0x3 << SSEL0_BIT); + LPC_PINCON->PINSEL1 |= (SSEL0_FUNCTION << SSEL0_BIT); + + LPC_PINCON->PINSEL1 &= ~(0x3 << MISO0_BIT); + LPC_PINCON->PINSEL1 |= (MISO0_FUNCTION << MISO0_BIT); + + LPC_PINCON->PINSEL1 &= ~(0x3 << MOSI0_BIT); + LPC_PINCON->PINSEL1 |= (MOSI0_FUNCTION << MOSI0_BIT); + + // Enable SPI interrupt: + // Set SPI interrupt flag (see table 367) + LPC_SPI->SPINT = 1; + + // Enable SPI interrupt in the NVIC (see table 50) + NVIC_EnableIRQ(SPI_IRQn); +#endif/*USE_CMSIS*/ + + // Configure SSEL pin: + LPC_GPIO1->FIODIR |= 1 << 21; // Set 1.21 in output mode + +} + +void spi_deinit() +{ +#ifdef USE_CMSIS +#else/*USE_CMSIS*/ + // Power down SPI + LPC_SC->PCONP &= ~(1 << PCSPI_BIT); // unset bit 8 in PCONP (PCSPI bit) +#endif/*USE_CMSIS*/ +} + +// S0SPCR register (see table 361) +#define BENA 0 // Enable more than 8 bit transactions +#define CPHA 0 // CPHA (Clock Phase Control) \ _ Mode 0 +#define CPOL 0 // CPOL (Clock Polarity Control) / +#define MSTR 1 // MSTR (Master Mode Select) +#define LSB 1 // LSB vs MSB +#define SPIE 1 // Enable interrupts +#define BITS 0 // Bits to transfer, only use if BENA is set to 1 +void spi_configure() +{ +#ifdef USE_CMSIS +#else/*USE_CMSIS*/ + // S0SPCR register (see table 361) + LPC_SPI->SPCR = (BENA << 2) | (CPHA << 3) | (CPOL << 4) | (MSTR << 5) | + (LSB << 6) | (SPIE << 7) | (BITS << 8); + + LPC_SPI->SPCCR = 1; +#endif/*USE_CMSIS*/ +} + +static volatile int spi_done = 0; +static void spi_mark_as_done() +{ + spi_done = 1; +} + +volatile int temp; +void __delay(uint32_t del) +{ + uint32_t i; + for(i=0;iFIOPIN &= ~( 1 << 21 ); // make P1.21 low + + spi_done = 0; + SPI_ReadWrite(spi, &dst, SPI_TRANSFER_POLLING);//SPI_TRANSFER_INTERRUPT); + + cli_write(">"); + while (!(SPI_GetStatus(spi) & SPI_SPSR_SPIF)) { } + //while(!spi_done) {} + cli_write("<"); + + LPC_GPIO1->FIOPIN |= 1 << 21; // make P1.29 high + +#else/*USE_CMSIS*/ + + int i = 0; + cli_write(">>"); + + LPC_GPIO1->FIOPIN &= ~( 1 << 21 ); // make P1.21 low + + for(; i < length; i++) { + /* + cli_write("w"); + LPC_GPIO1->FIOPIN &= ~( 1 << 21 ); // make P1.21 low + __delay(1 << 23); + */ + + //LPC_SPI->SPINT = 1; // Clear interrupt (see section 17.7.7) + //if(LPC_SPI->SPSR) {} // Make sure we clear the status register + + LPC_SPI->SPDR = tx_data[i]; + + //cli_write("[%d]", tx_data[i]); + + //if(LPC_SPI->SPSR) {} // Make sure we clear the status register + + // Check SPIF bit (see table 362) + //while(((LPC_SPI->SPSR << 7) & 0x1) != 1) {} + //while(LPC_SPI->SPSR == 0) {} // Wait for status register + while(LPC_SPI->SPINT == 0) {} // Wait for interrupt + LPC_SPI->SPINT = 1; + //__delay(1 << 23); + + // cli_write("{%d}", LPC_SPI->SPSR); + + rx_data[i] = LPC_SPI->SPDR; + //cli_write("[%d]", rx_data[i]); + + /* + cli_write("r"); + LPC_GPIO1->FIOPIN |= 1 << 21; // make P1.29 high + __delay(1 << 23); + */ + } + + LPC_GPIO1->FIOPIN |= 1 << 21; // make P1.29 high + + cli_write("<<"); +#endif/*USE_CMSIS*/ +} diff --git a/firmware/drivers/spi.h b/firmware/drivers/spi.h new file mode 100644 index 0000000..b2ecf5a --- /dev/null +++ b/firmware/drivers/spi.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * spi.h + * + * Sun Jun 9 14:02:49 CEST 2013 + * Copyright 2013 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PEDAL2METAL_SPI_H__ +#define __PEDAL2METAL_SPI_H__ + +#include +#include + +void spi_init(); +void spi_deinit(); +void spi_read_write(uint8_t *tx_data, uint8_t *rx_data, size_t length); + +#endif/*__PEDAL2METAL_SPI_H__*/ diff --git a/firmware/drivers/uart.c b/firmware/drivers/uart.c new file mode 100644 index 0000000..28a6e00 --- /dev/null +++ b/firmware/drivers/uart.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * $Id:: uart.c 5751 2010-11-30 23:56:11Z usb00423 $ + * Project: NXP LPC17xx UART example + * + * Description: + * This file contains UART code example which include UART initialization, + * UART interrupt handler, and APIs for UART access. + * + **************************************************************************** + * 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. +****************************************************************************/ +#include +#include //"type.h" +#include "uart.h" + +#define TRUE 1 +#define FALSE 0 + +volatile uint32_t UART0Status, UART1Status; +volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1; + +/***************************************************************************** +** Function name: UARTInit +** +** Descriptions: Initialize UART port, setup pin select, +** clock, parity, stop bits, FIFO, etc. +** +** parameters: portNum(0 or 1) and UART baudrate +** Returned value: true or false, return false only if the +** interrupt handler can't be installed to the +** VIC table +** +*****************************************************************************/ +uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate ) +{ + uint32_t Fdiv; + uint32_t pclkdiv, pclk; + + uint32_t SystemFrequency = SystemCoreClock; + + if ( PortNum == 0 ) + { + LPC_PINCON->PINSEL0 &= ~0x000000F0; + LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */ + /* By default, the PCLKSELx value is zero, thus, the PCLK for + all the peripherals is 1/4 of the SystemFrequency. */ + /* Bit 6~7 is for UART0 */ + pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03; + switch ( pclkdiv ) + { + case 0x00: + default: + pclk = SystemFrequency/4; + break; + case 0x01: + pclk = SystemFrequency; + break; + case 0x02: + pclk = SystemFrequency/2; + break; + case 0x03: + pclk = SystemFrequency/8; + break; + } + + LPC_UART0->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ + Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */ + LPC_UART0->DLM = Fdiv / 256; + LPC_UART0->DLL = Fdiv % 256; + LPC_UART0->LCR = 0x03; /* DLAB = 0 */ + LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ + + // NVIC_EnableIRQ(UART0_IRQn); + + //LPC_UART0->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */ + return (TRUE); + } + else if ( PortNum == 1 ) + { + LPC_PINCON->PINSEL4 &= ~0x0000000F; + LPC_PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */ + + /* By default, the PCLKSELx value is zero, thus, the PCLK for + all the peripherals is 1/4 of the SystemFrequency. */ + /* Bit 8,9 are for UART1 */ + pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03; + switch ( pclkdiv ) + { + case 0x00: + default: + pclk = SystemFrequency/4; + break; + case 0x01: + pclk = SystemFrequency; + break; + case 0x02: + pclk = SystemFrequency/2; + break; + case 0x03: + pclk = SystemFrequency/8; + break; + } + + LPC_UART1->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ + Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */ + LPC_UART1->DLM = Fdiv / 256; + LPC_UART1->DLL = Fdiv % 256; + LPC_UART1->LCR = 0x03; /* DLAB = 0 */ + LPC_UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ + + // NVIC_EnableIRQ(UART1_IRQn); + + LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART1 interrupt */ + return (TRUE); + } + return( FALSE ); +} + +/***************************************************************************** +** Function name: UARTSend +** +** Descriptions: Send a block of data to the UART 0 port based +** on the data length +** +** parameters: portNum, buffer pointer, and data length +** Returned value: None +** +*****************************************************************************/ +void UARTSend( uint32_t portNum, char *BufferPtr, uint32_t Length ) +{ + if ( portNum == 0 ) + { + while ( Length != 0 ) + { + /* THRE status, contain valid data */ + //while ( !(UART0TxEmpty & 0x01) ); + LPC_UART0->THR = *BufferPtr; + UART0TxEmpty = 0; /* not empty in the THR until it shifts out */ + BufferPtr++; + Length--; + } + } + else + { + while ( Length != 0 ) + { + /* THRE status, contain valid data */ + while ( !(UART1TxEmpty & 0x01) ); + LPC_UART1->THR = *BufferPtr; + UART1TxEmpty = 0; /* not empty in the THR until it shifts out */ + BufferPtr++; + Length--; + } + } + return; +} + +/****************************************************************************** +** End Of File +******************************************************************************/ diff --git a/firmware/drivers/uart.h b/firmware/drivers/uart.h new file mode 100644 index 0000000..24b8259 --- /dev/null +++ b/firmware/drivers/uart.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * $Id:: uart.h 5751 2010-11-30 23:56:11Z usb00423 $ + * Project: NXP LPC17xx UART example + * + * Description: + * This file contains UART 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 __UART_H +#define __UART_H + +#include + +#define IER_RBR 0x01 +#define IER_THRE 0x02 +#define IER_RLS 0x04 + +#define IIR_PEND 0x01 +#define IIR_RLS 0x03 +#define IIR_RDA 0x02 +#define IIR_CTI 0x06 +#define IIR_THRE 0x01 + +#define LSR_RDR 0x01 +#define LSR_OE 0x02 +#define LSR_PE 0x04 +#define LSR_FE 0x08 +#define LSR_BI 0x10 +#define LSR_THRE 0x20 +#define LSR_TEMT 0x40 +#define LSR_RXFE 0x80 + +#define BUFSIZE 0x40 + +uint32_t UARTInit( uint32_t portNum, uint32_t Baudrate ); +void UARTSend(uint32_t portNum, char *BufferPtr, uint32_t Length ); + +#endif /* end __UART_H */ +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/firmware/drivers/wm8523.c b/firmware/drivers/wm8523.c index 36d293a..08b8d97 100644 --- a/firmware/drivers/wm8523.c +++ b/firmware/drivers/wm8523.c @@ -27,100 +27,69 @@ #include "wm8523.h" #include -#include +#include + +#include "spi.h" #define WM8523_WRITE 0 #define WM8523_READ 1 -static SPI_CFG_Type spi_cfg; -static LPC_SPI_TypeDef spi; - -typedef struct __attribute__ ((packed)) { - uint8_t rw:1; ///< See WM8523_WRITE and WM8523_READ - uint8_t reg:7; ///< See page 35 in the WM8523 manual. - uint16_t data; +typedef union { + struct __attribute__ ((packed)) { + uint8_t rw:1; ///< See WM8523_WRITE and WM8523_READ + uint8_t reg:7; ///< See page 35 in the WM8523 manual. + uint16_t data; + } val; + uint8_t data[3]; } WM8523_transfer_t; -void WM8523_Init() -{ - // 16 bit data tranfers - spi_cfg.Databit = SPI_DATABIT_16; - - // WM8523 samples bits on rising edges. Mode 0 or 3 will work - // http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase - - // Mode 0 - spi_cfg.CPHA = SPI_CPHA_FIRST; // 0 - spi_cfg.CPOL = SPI_CPOL_HI; // 0 - /* - // Mode 3 - spi_cfg.CPHA = SPI_CPHA_SECOND; // 1 - spi_cfg.CPOL = SPI_CPOL_LO; // 1 - */ - - // We are the master - spi_cfg.Mode = SPI_MASTER_MODE; - - // We run on a little endian mcu. - spi_cfg.DataOrder = SPI_DATA_LSB_FIRST; - - // Se WM8523 manual page 14. Min clock pulse width 40ns ~= 25MHz - spi_cfg.ClockRate = 1000000000; // 1MHz - - SPI_Init(&spi, &spi_cfg); +void WM8523_init() +{ + cli_write("sizeof: %d", sizeof(WM8523_transfer_t)); + spi_init(); } -static volatile int spi_done = 0; -void spi_mark_as_done() +void WM8523_deinit() { - spi_done = 1; + spi_deinit(); } -static void send(void *data, size_t size) +void WM8523_write(uint8_t reg, uint16_t data) { - SPI_DATA_SETUP_Type dst; - memset(&dst, 0, sizeof(dst)); - dst.rx_data = data; - dst.length = size; - dst.callback = spi_mark_as_done; - - spi_done = 0; - SPI_ReadWrite(&spi, &dst, SPI_TRANSFER_INTERRUPT); + WM8523_transfer_t t; + t.val.rw = WM8523_WRITE; + t.val.reg = reg; + t.val.data = data; - while(!spi_done) {} + WM8523_transfer_t r; + r.val.data = 0xffff; + + spi_read_write(t.data, r.data, 3); } -static void receive(void *data, size_t size) +uint16_t WM8523_read(uint8_t reg) { - // http://anhnvnguyen.blogspot.dk/2010/04/lpc17xx-gpio-basic_05.html - // TODO: set SSEL0 low - // PINSEL3[13:12] = p1.21 (SSEL0) - LPC_PINCON->PINSEL3 &= ~((1<<13)|(1<<12)); // set to 00 - - SPI_DATA_SETUP_Type dst; - memset(&dst, 0, sizeof(dst)); - dst.tx_data = data; - dst.length = size; - dst.callback = spi_mark_as_done; + WM8523_transfer_t t; + t.val.rw = WM8523_READ; + t.val.reg = reg; + t.val.data = 0xffff; - spi_done = 0; - SPI_ReadWrite(&spi, &dst, SPI_TRANSFER_INTERRUPT); - - while(!spi_done) {} + WM8523_transfer_t r; - // TODO: set SSEL0 high + spi_read_write(t.data, r.data, 3); + + return r.data[0] | (r.data[1] << 8);//r.val.data; } /** Volume update registers R06h and R07h are unavailable in SPI control mode. To use volume update in software control mode, I2C mode must be used. */ -void WM8523_Configure() +void WM8523_configure() { - WM8523_transfer_t transfer; - transfer.rw = WM8523_READ; - transfer.reg = 0; // R0 read version : 0x8523 - transfer.data = 0; - //send(&transfer, sizeof(transfer)); - receive(&transfer, sizeof(transfer)); + spi_configure(); + + uint16_t id = WM8523_read(0); // Read chip id from reg0. + + cli_write("=%d=", id); // should be 34595 (0x8523) } diff --git a/firmware/drivers/wm8523.h b/firmware/drivers/wm8523.h index 085b1f4..e1bb8bc 100644 --- a/firmware/drivers/wm8523.h +++ b/firmware/drivers/wm8523.h @@ -27,7 +27,11 @@ #ifndef __PEDAL2METAL_WM8523_H__ #define __PEDAL2METAL_WM8523_H__ -void WM8523_Init(); -void WM8523_Configure(); +#include + +void WM8523_init(); +void WM8523_configure(); +uint16_t WM8523_read(uint8_t reg); +void WM8523_write(uint8_t reg, uint16_t data); #endif/*__PEDAL2METAL_WM8523_H__*/ diff --git a/firmware/lpc17xx/lpc17xx_pinsel.c b/firmware/lpc17xx/lpc17xx_pinsel.c new file mode 100644 index 0000000..c459217 --- /dev/null +++ b/firmware/lpc17xx/lpc17xx_pinsel.c @@ -0,0 +1,308 @@ +/** + * @file : lpc17xx_pinsel.c + * @brief : Contains all functions support for Pin connect block firmware + * library on LPC17xx + * @version : 1.0 + * @date : 25. Feb. 2009 + * @author : HoanTran + ************************************************************************** + * 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. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup PINSEL + * @{ + */ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx_pinsel.h" + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup PINSEL_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Setup the pin selection function + * @param[in] portnum PORT number, + * should be one of the following: + * - PINSEL_PORT_0 : Port 0 + * - PINSEL_PORT_1 : Port 1 + * - PINSEL_PORT_2 : Port 2 + * - PINSEL_PORT_3 : Port 3 + * + * @param[in] pinnum Pin number, + * should be one of the following: + - PINSEL_PIN_0 : Pin 0 + - PINSEL_PIN_1 : Pin 1 + - PINSEL_PIN_2 : Pin 2 + - PINSEL_PIN_3 : Pin 3 + - PINSEL_PIN_4 : Pin 4 + - PINSEL_PIN_5 : Pin 5 + - PINSEL_PIN_6 : Pin 6 + - PINSEL_PIN_7 : Pin 7 + - PINSEL_PIN_8 : Pin 8 + - PINSEL_PIN_9 : Pin 9 + - PINSEL_PIN_10 : Pin 10 + - PINSEL_PIN_11 : Pin 11 + - PINSEL_PIN_12 : Pin 12 + - PINSEL_PIN_13 : Pin 13 + - PINSEL_PIN_14 : Pin 14 + - PINSEL_PIN_15 : Pin 15 + - PINSEL_PIN_16 : Pin 16 + - PINSEL_PIN_17 : Pin 17 + - PINSEL_PIN_18 : Pin 18 + - PINSEL_PIN_19 : Pin 19 + - PINSEL_PIN_20 : Pin 20 + - PINSEL_PIN_21 : Pin 21 + - PINSEL_PIN_22 : Pin 22 + - PINSEL_PIN_23 : Pin 23 + - PINSEL_PIN_24 : Pin 24 + - PINSEL_PIN_25 : Pin 25 + - PINSEL_PIN_26 : Pin 26 + - PINSEL_PIN_27 : Pin 27 + - PINSEL_PIN_28 : Pin 28 + - PINSEL_PIN_29 : Pin 29 + - PINSEL_PIN_30 : Pin 30 + - PINSEL_PIN_31 : Pin 31 + + * @param[in] funcnum Function number, + * should be one of the following: + * - PINSEL_FUNC_0 : default function + * - PINSEL_FUNC_1 : first alternate function + * - PINSEL_FUNC_2 : second alternate function + * - PINSEL_FUNC_3 : third alternate function + * + * @return None + **********************************************************************/ +void PINSEL_SetPinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum) +{ + uint32_t pinnum_t = pinnum; + uint32_t pinselreg_idx = 2 * portnum; + uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINSEL0; + + if (pinnum_t >= 16) { + pinnum_t -= 16; + pinselreg_idx++; + } + *(uint32_t *)(pPinCon + pinselreg_idx) &= ~(0x03UL << (pinnum_t * 2)); + *(uint32_t *)(pPinCon + pinselreg_idx) |= ((uint32_t)funcnum) << (pinnum_t * 2); +} + + + +/*********************************************************************//** + * @brief Configure trace function + * @param[in] NewState State of the Trace function configuration, + * should be one of the following: + * - ENABLE : Enable Trace Function + * - DISABLE : Disable Trace Function + * + * @return None + **********************************************************************/ +void PINSEL_ConfigTraceFunc(FunctionalState NewState) +{ + if (NewState == ENABLE) { + LPC_PINCON->PINSEL10 |= (0x01UL << 3); + } else if (NewState == DISABLE) { + LPC_PINCON->PINSEL10 &= ~(0x01UL << 3); + } +} + + + +/*********************************************************************//** + * @brief Setup resistor mode for each pin + * @param[in] portnum PORT number, + * should be one of the following: + * - PINSEL_PORT_0 : Port 0 + * - PINSEL_PORT_1 : Port 1 + * - PINSEL_PORT_2 : Port 2 + * - PINSEL_PORT_3 : Port 3 + * @param[in] pinnum Pin number, + * should be one of the following: + - PINSEL_PIN_0 : Pin 0 + - PINSEL_PIN_1 : Pin 1 + - PINSEL_PIN_2 : Pin 2 + - PINSEL_PIN_3 : Pin 3 + - PINSEL_PIN_4 : Pin 4 + - PINSEL_PIN_5 : Pin 5 + - PINSEL_PIN_6 : Pin 6 + - PINSEL_PIN_7 : Pin 7 + - PINSEL_PIN_8 : Pin 8 + - PINSEL_PIN_9 : Pin 9 + - PINSEL_PIN_10 : Pin 10 + - PINSEL_PIN_11 : Pin 11 + - PINSEL_PIN_12 : Pin 12 + - PINSEL_PIN_13 : Pin 13 + - PINSEL_PIN_14 : Pin 14 + - PINSEL_PIN_15 : Pin 15 + - PINSEL_PIN_16 : Pin 16 + - PINSEL_PIN_17 : Pin 17 + - PINSEL_PIN_18 : Pin 18 + - PINSEL_PIN_19 : Pin 19 + - PINSEL_PIN_20 : Pin 20 + - PINSEL_PIN_21 : Pin 21 + - PINSEL_PIN_22 : Pin 22 + - PINSEL_PIN_23 : Pin 23 + - PINSEL_PIN_24 : Pin 24 + - PINSEL_PIN_25 : Pin 25 + - PINSEL_PIN_26 : Pin 26 + - PINSEL_PIN_27 : Pin 27 + - PINSEL_PIN_28 : Pin 28 + - PINSEL_PIN_29 : Pin 29 + - PINSEL_PIN_30 : Pin 30 + - PINSEL_PIN_31 : Pin 31 + + * @param[in] modenum: Mode number, + * should be one of the following: + - PINSEL_PINMODE_PULLUP : Internal pull-up resistor + - PINSEL_PINMODE_TRISTATE : Tri-state + - PINSEL_PINMODE_PULLDOWN : Internal pull-down resistor + + * @return None + **********************************************************************/ +void PINSEL_SetResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum) +{ + uint32_t pinnum_t = pinnum; + uint32_t pinmodereg_idx = 2 * portnum; + uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE0; + + if (pinnum_t >= 16) { + pinnum_t -= 16; + pinmodereg_idx++ ; + } + + *(uint32_t *)(pPinCon + pinmodereg_idx) &= ~(0x03UL << (pinnum_t * 2)); + *(uint32_t *)(pPinCon + pinmodereg_idx) |= ((uint32_t)modenum) << (pinnum_t * 2); +} + + + +/*********************************************************************//** + * @brief Setup Open drain mode for each pin + * @param[in] portnum PORT number, + * should be one of the following: + * - PINSEL_PORT_0 : Port 0 + * - PINSEL_PORT_1 : Port 1 + * - PINSEL_PORT_2 : Port 2 + * - PINSEL_PORT_3 : Port 3 + * + * @param[in] pinnum Pin number, + * should be one of the following: + - PINSEL_PIN_0 : Pin 0 + - PINSEL_PIN_1 : Pin 1 + - PINSEL_PIN_2 : Pin 2 + - PINSEL_PIN_3 : Pin 3 + - PINSEL_PIN_4 : Pin 4 + - PINSEL_PIN_5 : Pin 5 + - PINSEL_PIN_6 : Pin 6 + - PINSEL_PIN_7 : Pin 7 + - PINSEL_PIN_8 : Pin 8 + - PINSEL_PIN_9 : Pin 9 + - PINSEL_PIN_10 : Pin 10 + - PINSEL_PIN_11 : Pin 11 + - PINSEL_PIN_12 : Pin 12 + - PINSEL_PIN_13 : Pin 13 + - PINSEL_PIN_14 : Pin 14 + - PINSEL_PIN_15 : Pin 15 + - PINSEL_PIN_16 : Pin 16 + - PINSEL_PIN_17 : Pin 17 + - PINSEL_PIN_18 : Pin 18 + - PINSEL_PIN_19 : Pin 19 + - PINSEL_PIN_20 : Pin 20 + - PINSEL_PIN_21 : Pin 21 + - PINSEL_PIN_22 : Pin 22 + - PINSEL_PIN_23 : Pin 23 + - PINSEL_PIN_24 : Pin 24 + - PINSEL_PIN_25 : Pin 25 + - PINSEL_PIN_26 : Pin 26 + - PINSEL_PIN_27 : Pin 27 + - PINSEL_PIN_28 : Pin 28 + - PINSEL_PIN_29 : Pin 29 + - PINSEL_PIN_30 : Pin 30 + - PINSEL_PIN_31 : Pin 31 + + * @param[in] modenum Open drain mode number, + * should be one of the following: + * - PINSEL_PINMODE_NORMAL : Pin is in the normal (not open drain) mode + * - PINSEL_PINMODE_OPENDRAIN : Pin is in the open drain mode + * + * @return None + **********************************************************************/ +void PINSEL_SetOpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum) +{ + uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE_OD0; + + if (modenum == PINSEL_PINMODE_OPENDRAIN){ + *(uint32_t *)(pPinCon + portnum) |= (0x01UL << pinnum); + } else { + *(uint32_t *)(pPinCon + portnum) &= ~(0x01UL << pinnum); + } +} + + + +/*********************************************************************//** + * @brief Setup I2C0 pins + * @param[in] i2cPinMode I2C pin mode, + * should be one of the following: + * - PINSEL_I2C_Normal_Mode : The standard drive mode + * - PINSEL_I2C_Fast_Mode : Fast Mode Plus drive mode + * + * @param[in] filterSlewRateEnable should be: + * - ENABLE: Enable filter and slew rate. + * - DISABLE: Disable filter and slew rate. + * + * @return None + **********************************************************************/ +void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable) +{ + uint32_t regVal; + + if (i2cPinMode == PINSEL_I2C_Fast_Mode){ + regVal = PINSEL_I2CPADCFG_SCLDRV0 | PINSEL_I2CPADCFG_SDADRV0; + } + + if (filterSlewRateEnable == DISABLE){ + regVal = PINSEL_I2CPADCFG_SCLI2C0 | PINSEL_I2CPADCFG_SDAI2C0; + } + LPC_PINCON->I2CPADCFG = regVal; +} + + +/*********************************************************************//** + * @brief Configure Pin corresponding to specified parameters passed + * in the PinCfg + * @param[in] PinCfg Pointer to a PINSEL_CFG_Type structure + * that contains the configuration information for the + * specified pin. + * @return None + **********************************************************************/ +void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg) +{ + PINSEL_SetPinFunc(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Funcnum); + PINSEL_SetResistorMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Pinmode); + PINSEL_SetOpenDrainMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->OpenDrain); +} + + +/** + * @} + */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/firmware/lpc17xx/lpc17xx_pinsel.h b/firmware/lpc17xx/lpc17xx_pinsel.h new file mode 100644 index 0000000..6d46b73 --- /dev/null +++ b/firmware/lpc17xx/lpc17xx_pinsel.h @@ -0,0 +1,210 @@ +/***********************************************************************//** + * @file : lpc17xx_pinsel.h + * @brief : Contains all macro definitions and function prototypes + * support for Pin connect block firmware library on LPC17xx + * @version : 1.0 + * @date : 25. Feb. 2009 + * @author : HoanTran + ************************************************************************** + * 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. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup PINSEL + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_PINSEL_H_ +#define LPC17XX_PINSEL_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup PINSEL_Private_Macros + * @{ + */ + +/** @defgroup PINSEL_REGISTER_BIT_DEFINITIONS + * @{ + */ + +/* Pin selection define */ +/* I2C Pin Configuration register bit description */ +#define PINSEL_I2CPADCFG_SDADRV0 _BIT(0) /**< Drive mode control for the SDA0 pin, P0.27 */ +#define PINSEL_I2CPADCFG_SDAI2C0 _BIT(1) /**< I2C mode control for the SDA0 pin, P0.27 */ +#define PINSEL_I2CPADCFG_SCLDRV0 _BIT(2) /**< Drive mode control for the SCL0 pin, P0.28 */ +#define PINSEL_I2CPADCFG_SCLI2C0 _BIT(3) /**< I2C mode control for the SCL0 pin, P0.28 */ + +/** + * @} + */ + +/** + * @} + */ + + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup PINSEL_Public_Macros + * @{ + */ + +/*********************************************************************//** + *!< Macros define for PORT Selection + ***********************************************************************/ +#define PINSEL_PORT_0 ((0)) /**< PORT 0*/ +#define PINSEL_PORT_1 ((1)) /**< PORT 1*/ +#define PINSEL_PORT_2 ((2)) /**< PORT 2*/ +#define PINSEL_PORT_3 ((3)) /**< PORT 3*/ +#define PINSEL_PORT_4 ((4)) /**< PORT 4*/ + + +/*********************************************************************** + * Macros define for Pin Function selection + **********************************************************************/ +#define PINSEL_FUNC_0 ((0)) /**< default function*/ +#define PINSEL_FUNC_1 ((1)) /**< first alternate function*/ +#define PINSEL_FUNC_2 ((2)) /**< second alternate function*/ +#define PINSEL_FUNC_3 ((3)) /**< third or reserved alternate function*/ + + + +/*********************************************************************** + * Macros define for Pin Number of Port + **********************************************************************/ +#define PINSEL_PIN_0 ((0)) /**< Pin 0 */ +#define PINSEL_PIN_1 ((1)) /**< Pin 1 */ +#define PINSEL_PIN_2 ((2)) /**< Pin 2 */ +#define PINSEL_PIN_3 ((3)) /**< Pin 3 */ +#define PINSEL_PIN_4 ((4)) /**< Pin 4 */ +#define PINSEL_PIN_5 ((5)) /**< Pin 5 */ +#define PINSEL_PIN_6 ((6)) /**< Pin 6 */ +#define PINSEL_PIN_7 ((7)) /**< Pin 7 */ +#define PINSEL_PIN_8 ((8)) /**< Pin 8 */ +#define PINSEL_PIN_9 ((9)) /**< Pin 9 */ +#define PINSEL_PIN_10 ((10)) /**< Pin 10 */ +#define PINSEL_PIN_11 ((11)) /**< Pin 11 */ +#define PINSEL_PIN_12 ((12)) /**< Pin 12 */ +#define PINSEL_PIN_13 ((13)) /**< Pin 13 */ +#define PINSEL_PIN_14 ((14)) /**< Pin 14 */ +#define PINSEL_PIN_15 ((15)) /**< Pin 15 */ +#define PINSEL_PIN_16 ((16)) /**< Pin 16 */ +#define PINSEL_PIN_17 ((17)) /**< Pin 17 */ +#define PINSEL_PIN_18 ((18)) /**< Pin 18 */ +#define PINSEL_PIN_19 ((19)) /**< Pin 19 */ +#define PINSEL_PIN_20 ((20)) /**< Pin 20 */ +#define PINSEL_PIN_21 ((21)) /**< Pin 21 */ +#define PINSEL_PIN_22 ((22)) /**< Pin 22 */ +#define PINSEL_PIN_23 ((23)) /**< Pin 23 */ +#define PINSEL_PIN_24 ((24)) /**< Pin 24 */ +#define PINSEL_PIN_25 ((25)) /**< Pin 25 */ +#define PINSEL_PIN_26 ((26)) /**< Pin 26 */ +#define PINSEL_PIN_27 ((27)) /**< Pin 27 */ +#define PINSEL_PIN_28 ((28)) /**< Pin 28 */ +#define PINSEL_PIN_29 ((29)) /**< Pin 29 */ +#define PINSEL_PIN_30 ((30)) /**< Pin 30 */ +#define PINSEL_PIN_31 ((31)) /**< Pin 31 */ + + +/*********************************************************************** + * Macros define for Pin mode + **********************************************************************/ +#define PINSEL_PINMODE_PULLUP ((0)) /**< Internal pull-up resistor*/ +#define PINSEL_PINMODE_TRISTATE ((2)) /**< Tri-state */ +#define PINSEL_PINMODE_PULLDOWN ((3)) /**< Internal pull-down resistor */ + + +/*********************************************************************** + * Macros define for Pin mode (normal/open drain) + **********************************************************************/ +#define PINSEL_PINMODE_NORMAL ((0)) /**< Pin is in the normal (not open drain) mode.*/ +#define PINSEL_PINMODE_OPENDRAIN ((1)) /**< Pin is in the open drain mode */ + + +/*********************************************************************** + * Macros define for I2C mode + ***********************************************************************/ +#define PINSEL_I2C_Normal_Mode ((0)) /**< The standard drive mode */ +#define PINSEL_I2C_Fast_Mode ((1)) /**< Fast Mode Plus drive mode */ + + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup PINSEL_Public_Types + * @{ + */ + +/** @brief Pin configuration structure */ +typedef struct +{ + uint8_t Portnum; /**< Port Number, should be PINSEL_PORT_x, + where x should be in range from 0 to 4 */ + uint8_t Pinnum; /**< Pin Number, should be PINSEL_PIN_x, + where x should be in range from 0 to 31 */ + uint8_t Funcnum; /**< Function Number, should be PINSEL_FUNC_x, + where x should be in range from 0 to 3 */ + uint8_t Pinmode; /**< Pin Mode, should be: + - PINSEL_PINMODE_PULLUP: Internal pull-up resistor + - PINSEL_PINMODE_TRISTATE: Tri-state + - PINSEL_PINMODE_PULLDOWN: Internal pull-down resistor */ + uint8_t OpenDrain; /**< OpenDrain mode, should be: + - PINSEL_PINMODE_NORMAL: Pin is in the normal (not open drain) mode + - PINSEL_PINMODE_OPENDRAIN: Pin is in the open drain mode */ +} PINSEL_CFG_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup PINSEL_Public_Functions + * @{ + */ + +void PINSEL_SetPinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum); +void PINSEL_ConfigTraceFunc (FunctionalState NewState); +void PINSEL_SetResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum); +void PINSEL_SetOpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum); +void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable); +void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_PINSEL_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/firmware/lpc17xx/lpc17xx_spi.c b/firmware/lpc17xx/lpc17xx_spi.c index 622b1e7..b324116 100644 --- a/firmware/lpc17xx/lpc17xx_spi.c +++ b/firmware/lpc17xx/lpc17xx_spi.c @@ -26,6 +26,8 @@ #include "lpc17xx_spi.h" #include "lpc17xx_clkpwr.h" +#include + #define CHECK_PARAM(expr) /* Private Types -------------------------------------------------------------- */ @@ -63,6 +65,7 @@ static SPI_CFG_T spidat; ***********************************************************************/ void SPI_IntHandler(void) { + LED_on(); SPI_DATA_SETUP_Type *xf_setup; uint16_t tmp; diff --git a/firmware/src/p2m.c b/firmware/src/p2m.c index d4ecb21..3f4f2f2 100644 --- a/firmware/src/p2m.c +++ b/firmware/src/p2m.c @@ -91,24 +91,32 @@ int main (void) #ifdef SPI -#include "LPC17xx.h" -#include -#include "uart.h" +#include #include +#include int main (void) -{ - UARTInit(0, 115200); /* baud rate setting */ +{ + // SystemCoreClockUpdate(); + // SystemInit(); - UARTSend(0, (uint8_t *)"init\n\r", 6); + LED_Init(); - WM8523_Init(); + cli_init(); - while (1) { - UARTSend(0, (uint8_t *)"hello\n\r", 7); + cli_write("init"); - _delay( 1 << 22 ); - } + _delay(1 << 22); + + WM8523_init(); + + cli_write("pre"); + + _delay(1 << 22); + + WM8523_configure(); + + cli_write("post"); } #endif diff --git a/firmware/src/uart.c b/firmware/src/uart.c deleted file mode 100644 index d3ac789..0000000 --- a/firmware/src/uart.c +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** - * $Id:: uart.c 5751 2010-11-30 23:56:11Z usb00423 $ - * Project: NXP LPC17xx UART example - * - * Description: - * This file contains UART code example which include UART initialization, - * UART interrupt handler, and APIs for UART access. - * - **************************************************************************** - * 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. -****************************************************************************/ -#include -#include //"type.h" -#include "uart.h" - -#define TRUE 1 -#define FALSE 0 - -volatile uint32_t UART0Status, UART1Status; -volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1; - -/***************************************************************************** -** Function name: UARTInit -** -** Descriptions: Initialize UART port, setup pin select, -** clock, parity, stop bits, FIFO, etc. -** -** parameters: portNum(0 or 1) and UART baudrate -** Returned value: true or false, return false only if the -** interrupt handler can't be installed to the -** VIC table -** -*****************************************************************************/ -uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate ) -{ - uint32_t Fdiv; - uint32_t pclkdiv, pclk; - - uint32_t SystemFrequency = SystemCoreClock; - - if ( PortNum == 0 ) - { - LPC_PINCON->PINSEL0 &= ~0x000000F0; - LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */ - /* By default, the PCLKSELx value is zero, thus, the PCLK for - all the peripherals is 1/4 of the SystemFrequency. */ - /* Bit 6~7 is for UART0 */ - pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03; - switch ( pclkdiv ) - { - case 0x00: - default: - pclk = SystemFrequency/4; - break; - case 0x01: - pclk = SystemFrequency; - break; - case 0x02: - pclk = SystemFrequency/2; - break; - case 0x03: - pclk = SystemFrequency/8; - break; - } - - LPC_UART0->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ - Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */ - LPC_UART0->DLM = Fdiv / 256; - LPC_UART0->DLL = Fdiv % 256; - LPC_UART0->LCR = 0x03; /* DLAB = 0 */ - LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ - - // NVIC_EnableIRQ(UART0_IRQn); - - //LPC_UART0->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */ - return (TRUE); - } - else if ( PortNum == 1 ) - { - LPC_PINCON->PINSEL4 &= ~0x0000000F; - LPC_PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */ - - /* By default, the PCLKSELx value is zero, thus, the PCLK for - all the peripherals is 1/4 of the SystemFrequency. */ - /* Bit 8,9 are for UART1 */ - pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03; - switch ( pclkdiv ) - { - case 0x00: - default: - pclk = SystemFrequency/4; - break; - case 0x01: - pclk = SystemFrequency; - break; - case 0x02: - pclk = SystemFrequency/2; - break; - case 0x03: - pclk = SystemFrequency/8; - break; - } - - LPC_UART1->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ - Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */ - LPC_UART1->DLM = Fdiv / 256; - LPC_UART1->DLL = Fdiv % 256; - LPC_UART1->LCR = 0x03; /* DLAB = 0 */ - LPC_UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ - - // NVIC_EnableIRQ(UART1_IRQn); - - LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART1 interrupt */ - return (TRUE); - } - return( FALSE ); -} - -/***************************************************************************** -** Function name: UARTSend -** -** Descriptions: Send a block of data to the UART 0 port based -** on the data length -** -** parameters: portNum, buffer pointer, and data length -** Returned value: None -** -*****************************************************************************/ -void UARTSend( uint32_t portNum, uint8_t *BufferPtr, uint32_t Length ) -{ - if ( portNum == 0 ) - { - while ( Length != 0 ) - { - /* THRE status, contain valid data */ - //while ( !(UART0TxEmpty & 0x01) ); - LPC_UART0->THR = *BufferPtr; - UART0TxEmpty = 0; /* not empty in the THR until it shifts out */ - BufferPtr++; - Length--; - } - } - else - { - while ( Length != 0 ) - { - /* THRE status, contain valid data */ - while ( !(UART1TxEmpty & 0x01) ); - LPC_UART1->THR = *BufferPtr; - UART1TxEmpty = 0; /* not empty in the THR until it shifts out */ - BufferPtr++; - Length--; - } - } - return; -} - -/****************************************************************************** -** End Of File -******************************************************************************/ diff --git a/firmware/src/uart.h b/firmware/src/uart.h deleted file mode 100644 index 870f581..0000000 --- a/firmware/src/uart.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - * $Id:: uart.h 5751 2010-11-30 23:56:11Z usb00423 $ - * Project: NXP LPC17xx UART example - * - * Description: - * This file contains UART 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 __UART_H -#define __UART_H - -#define IER_RBR 0x01 -#define IER_THRE 0x02 -#define IER_RLS 0x04 - -#define IIR_PEND 0x01 -#define IIR_RLS 0x03 -#define IIR_RDA 0x02 -#define IIR_CTI 0x06 -#define IIR_THRE 0x01 - -#define LSR_RDR 0x01 -#define LSR_OE 0x02 -#define LSR_PE 0x04 -#define LSR_FE 0x08 -#define LSR_BI 0x10 -#define LSR_THRE 0x20 -#define LSR_TEMT 0x40 -#define LSR_RXFE 0x80 - -#define BUFSIZE 0x40 - -uint32_t UARTInit( uint32_t portNum, uint32_t Baudrate ); -void UARTSend(uint32_t portNum, uint8_t *BufferPtr, uint32_t Length ); - -#endif /* end __UART_H */ -/***************************************************************************** -** End Of File -******************************************************************************/ -- cgit v1.2.3