diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-07-30 00:39:22 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-07-30 00:39:55 +0200 |
commit | de0d7e35eed67bab478fda9eee7cb9edb1f34f04 (patch) | |
tree | 66a877977a02a21e0b93572f41cf9356c3ce87e4 /firmware/src | |
parent | 9f120cdf57b9dc2ca8112cbb89587f77df4facd2 (diff) |
simtrace: add some early spi flash utility routines
This also adds a new 'main_factory' target for simtrace
Diffstat (limited to 'firmware/src')
-rw-r--r-- | firmware/src/simtrace/main_factory.c | 80 | ||||
-rw-r--r-- | firmware/src/simtrace/spi_flash.c | 144 |
2 files changed, 224 insertions, 0 deletions
diff --git a/firmware/src/simtrace/main_factory.c b/firmware/src/simtrace/main_factory.c new file mode 100644 index 0000000..3585fa6 --- /dev/null +++ b/firmware/src/simtrace/main_factory.c @@ -0,0 +1,80 @@ +/* SIMtrace factory programming + * (C) 2011 by Harald Welte <hwelte@hmw-consulting.de> + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <errno.h> +#include <include/lib_AT91SAM7.h> +#include <include/openpcd.h> +#include <os/dbgu.h> +#include <os/led.h> +#include <os/pcd_enumerate.h> +#include <os/usb_handler.h> +#include "../openpcd.h" +#include "../simtrace.h" +#include <os/main.h> +#include <os/pio_irq.h> + +#include <simtrace/tc_etu.h> +#include <simtrace/iso7816_uart.h> +#include <simtrace/sim_switch.h> + +void _init_func(void) +{ + /* low-level hardware initialization */ + pio_irq_init(); + spiflash_init(); + + /* high-level protocol */ + //opicc_usbapi_init(); + led_switch(1, 0); + led_switch(2, 1); +} + +static void help(void) +{ + DEBUGPCR("f: read flash ID\r\n"); +} + +int _main_dbgu(char key) +{ + static int i = 0; + DEBUGPCRF("main_dbgu"); + + switch (key) { + case 'f': + spiflash_id(); + break; + case '?': + help(); + break; + } + + return -EINVAL; +} + +void _main_func(void) +{ + /* first we try to get rid of pending to-be-sent stuff */ + usb_out_process(); + + /* next we deal with incoming requests from USB EP1 (OUT) */ + usb_in_process(); + + udp_unthrottle(); +} diff --git a/firmware/src/simtrace/spi_flash.c b/firmware/src/simtrace/spi_flash.c new file mode 100644 index 0000000..98bc369 --- /dev/null +++ b/firmware/src/simtrace/spi_flash.c @@ -0,0 +1,144 @@ +/* Driver for a SST25VF040B spi flash attached to AT91SAM7 SPI + * (C) 2011 by Harald Welte <hwelte@hmw-consulting.de> + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <AT91SAM7.h> +#include <lib_AT91SAM7.h> +#include <openpcd.h> + +#include <simtrace_usb.h> + +#include <os/usb_handler.h> +#include <os/dbgu.h> +#include <os/pio_irq.h> + +#include "../simtrace.h" +#include "../openpcd.h" + +#define DEBUGPSPI DEBUGP +//#define DEBUGPSPI(x, y ...) do { } while (0) + +static const AT91PS_SPI pSPI = AT91C_BASE_SPI; + +void spiflash_write_protect(int on) +{ + if (on) + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PIO_SPIF_nWP); + else + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_SPIF_nWP); +} + +#define SPI_PERIPHA (PIO_SPIF_SCK|PIO_SPIF_MOSI|PIO_SPIF_MISO|PIO_SPIF_nCS) + +static __ramfunc void spi_irq(void) +{ + u_int32_t status = pSPI->SPI_SR; + + AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SPI); +} + +void spiflash_init(void) +{ + DEBUGP("spiflash_init\r\n"); + + /* activate and enable the write protection */ + AT91F_PIO_CfgPullupDis(AT91C_BASE_PIOA, PIO_SPIF_nWP); + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, PIO_SPIF_nWP); + spiflash_write_protect(1); + + /* Configure PIOs for SCK, MOSI, MISO and nCS */ + AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, SPI_PERIPHA, 0); + + AT91F_SPI_CfgPMC(); + /* Spansion flash in v1.0p only supprts Mode 3 or Mode 0 */ + /* Mode 3: CPOL=1 nCPHA=0 CSAAT=0 BITS=0(8) MCK/2 */ + AT91F_SPI_CfgCs(AT91C_BASE_SPI, 0, AT91C_SPI_CPOL | + AT91C_SPI_BITS_8 | + (64 << 8)); + + /* SPI master mode, fixed CS, CS = 0 */ + AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | + AT91C_SPI_PS_FIXED | + (0 << 16)); + + /* configure interrupt controller for SPI IRQ */ + AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SPI, + OPENPCD_IRQ_PRIO_SPI, + AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &spi_irq); + //AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI); + + /* Enable the SPI Controller */ + AT91F_SPI_Enable(AT91C_BASE_SPI); + AT91F_SPI_EnableIt(AT91C_BASE_SPI, AT91C_SPI_MODF | + AT91C_SPI_OVRES | + AT91C_SPI_ENDRX | + AT91C_SPI_ENDTX); +} + +static int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len, + u_int8_t *rx_data, u_int16_t *rx_len) +{ + u_int16_t tx_cur = 0; + u_int16_t rx_len_max = 0; + u_int16_t rx_cnt = 0; + + DEBUGPSPI("spi_transceive: enter(tx_len=%u) ", tx_len); + + if (rx_len) { + rx_len_max = *rx_len; + *rx_len = 0; + } + + //AT91F_SPI_Enable(pSPI); + while (1) { + u_int32_t sr = pSPI->SPI_SR; + u_int8_t tmp; + if (sr & AT91C_SPI_RDRF) { + tmp = pSPI->SPI_RDR; + rx_cnt++; + if (rx_len && *rx_len < rx_len_max) + rx_data[(*rx_len)++] = tmp; + } + if (sr & AT91C_SPI_TDRE) { + if (tx_len > tx_cur) + pSPI->SPI_TDR = tx_data[tx_cur++]; + } + if (tx_cur >= tx_len && rx_cnt >= tx_len) + break; + } + //AT91F_SPI_Disable(pSPI); + if (rx_data) + DEBUGPSPI(" leave(%02x %02x)\r\n", rx_data[0], rx_data[1]); + else + DEBUGPSPI("leave()\r\n"); + + return 0; +} + +void spiflash_id(void) +{ + const u_int8_t tx_data[] = { 0x9f, 0, 0, 0 }; + u_int8_t rx_data[] = { 0,0,0,0 }; + u_int16_t rx_len = sizeof(rx_data); + + spi_transceive(tx_data, sizeof(tx_data), rx_data, &rx_len); + DEBUGP("SPI ID: %02x %02x %02x\n", rx_data[1], rx_data[2], rx_data[3]); +} |