From 76c6c49a35c2c883fc303f0f29480dfe831eb69c Mon Sep 17 00:00:00 2001 From: aleph Date: Thu, 21 Oct 2010 10:24:53 +0000 Subject: [PATCH] sam3 spi: use data transfer register interrupt instead of tx finished interrupt: this way transfer is faster and we avoid chip select deasserting after each byte of a multi-byte transfer. Set all chip select registers at initialization, in case user change chip select manually (at the moment the spi driver doesn't have an API to change chip select). git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4442 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/ser_sam3.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/ser_sam3.c b/bertos/cpu/cortex-m3/drv/ser_sam3.c index ac902127..15b46dd1 100644 --- a/bertos/cpu/cortex-m3/drv/ser_sam3.c +++ b/bertos/cpu/cortex-m3/drv/ser_sam3.c @@ -533,14 +533,19 @@ static void spi0_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struc * Set SPI to master mode, fixed peripheral select, chip select directly connected to a peripheral device, * SPI clock set to MCK, mode fault detection disabled, loopback disable, NPCS0 active, Delay between CS = 0 */ - SPI0_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS); // | SPI_PCS_2; + SPI0_MR = BV(SPI_MSTR) | BV(SPI_MODFDIS); /* * Set SPI mode. * At reset clock division factor is set to 0, that is * *forbidden*. Set SPI clock to minimum to keep it valid. + * Set all possible chip select registers in case user manually + * change chip select. */ SPI0_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + SPI0_CSR1 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + SPI0_CSR2 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + SPI0_CSR3 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); /* Disable all irqs */ SPI0_IDR = 0xFFFFFFFF; @@ -579,7 +584,7 @@ static void spi0_starttx(struct SerialHardware *_hw) hw->sending = true; SPI0_TDR = fifo_pop(&ser_handles[SER_SPI0]->txfifo); /* Enable interrupt on tx buffer empty */ - SPI0_IER = BV(SPI_TXEMPTY); + SPI0_IER = BV(SPI_TDRE); } IRQ_RESTORE(flags); @@ -612,8 +617,13 @@ static void spi1_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struc * Set SPI mode. * At reset clock division factor is set to 0, that is * *forbidden*. Set SPI clock to minimum to keep it valid. + * Set all possible chip select registers in case user manually + * change chip select. */ SPI1_CSR0 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + SPI1_CSR1 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + SPI1_CSR2 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); + SPI1_CSR3 = BV(SPI_NCPHA) | (255 << SPI_SCBR_SHIFT); /* Disable all SPI irqs */ SPI1_IDR = 0xFFFFFFFF; @@ -652,7 +662,7 @@ static void spi1_starttx(struct SerialHardware *_hw) hw->sending = true; SPI1_TDR = fifo_pop(&ser_handles[SER_SPI1]->txfifo); /* Enable interrupt on tx buffer empty */ - SPI1_IER = BV(SPI_TXEMPTY); + SPI1_IER = BV(SPI_TDRE); } IRQ_RESTORE(flags); @@ -937,7 +947,7 @@ static DECLARE_ISR(spi0_irq_handler) { UARTDescs[SER_SPI0].sending = false; /* Disable interrupt on tx buffer empty */ - SPI0_IDR = BV(SPI_TXEMPTY); + SPI0_IDR = BV(SPI_TDRE); } SER_INT_ACK; @@ -971,7 +981,7 @@ static DECLARE_ISR(spi1_irq_handler) { UARTDescs[SER_SPI1].sending = false; /* Disable interrupt on tx buffer empty */ - SPI1_IDR = BV(SPI_TXEMPTY); + SPI1_IDR = BV(SPI_TDRE); } SER_INT_ACK; -- 2.25.1