00001
00028 #include <gpio.h>
00029 #include <intc.h>
00030 #include <avr32/io.h>
00031 #include <compiler.h>
00032 #include <string.h>
00033 #include <board.h>
00034 #include "printf-stdarg.h"
00035 #include "platform_spi.h"
00036
00037
00038
00039
00040 #if EXT_BOARD == SPB104
00041 #define USE_POLL
00042 #endif
00043
00044 #if BOARD == EVK1100
00045 #define AVR32_SPI AVR32_SPI1
00046 #define GPIO_IRQ_PIN AVR32_PIN_PB30
00047 #define GPIO_IRQ AVR32_GPIO_IRQ_7
00048 #define AVR32_PDCA_PID_TX AVR32_PDCA_PID_SPI1_TX
00049 #define AVR32_PDCA_PID_RX AVR32_PDCA_PID_SPI1_RX
00050 #define SPI_CS 1
00051 #elif BOARD == EVK1101
00052 #define GPIO_IRQ_PIN AVR32_PIN_PB00
00053 #define GPIO_IRQ AVR32_GPIO_IRQ_4
00054 #define AVR32_PDCA_PID_TX AVR32_PDCA_PID_SPI_TX
00055 #define AVR32_PDCA_PID_RX AVR32_PDCA_PID_SPI_RX
00056 #define SPI_CS 1
00057 #elif BOARD == EVK1105
00058 #define AVR32_SPI AVR32_SPI0
00059 #define GPIO_IRQ_PIN AVR32_PIN_PB30
00060 #define GPIO_IRQ AVR32_GPIO_IRQ_7
00061 #define AVR32_PDCA_PID_TX AVR32_PDCA_PID_SPI0_TX
00062 #define AVR32_PDCA_PID_RX AVR32_PDCA_PID_SPI0_RX
00063 #if EXT_BOARD == SPB105
00064 #define SPI_CS 2
00065 #elif EXT_BOARD == SPB104
00066 #define SPI_CS 1
00067 #else
00068 #error
00069 #endif
00070 #else
00071 #error
00072 #endif
00073
00074 #define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
00075
00076 __attribute__((__interrupt__)) void avr32_irq_handler(void);
00077
00078 void platform_init(U8 *flags)
00079 {
00080 #ifdef _ASSERT_ENABLE_
00081 volatile avr32_pm_t *pm = &AVR32_PM;
00082 #endif
00083 const gpio_map_t GPIO_MAP = {
00084
00085
00086 #if BOARD == EVK1100
00087 { AVR32_SPI1_NPCS_0_0_PIN, AVR32_SPI1_NPCS_0_0_FUNCTION },
00088 { AVR32_SPI1_NPCS_1_0_PIN, AVR32_SPI1_NPCS_1_0_FUNCTION },
00089 { AVR32_SPI1_MISO_0_0_PIN, AVR32_SPI1_MISO_0_0_FUNCTION },
00090 { AVR32_SPI1_MOSI_0_0_PIN, AVR32_SPI1_MOSI_0_0_FUNCTION },
00091 { AVR32_SPI1_SCK_0_0_PIN, AVR32_SPI1_SCK_0_0_FUNCTION },
00092
00093
00094 #elif BOARD == EVK1101
00095 { AVR32_SPI_NPCS_0_0_PIN, AVR32_SPI_NPCS_0_0_FUNCTION },
00096 { AVR32_SPI_NPCS_1_0_PIN, AVR32_SPI_NPCS_1_0_FUNCTION },
00097 { AVR32_SPI_MISO_0_0_PIN, AVR32_SPI_MISO_0_0_FUNCTION },
00098 { AVR32_SPI_MOSI_0_0_PIN, AVR32_SPI_MOSI_0_0_FUNCTION },
00099 { AVR32_SPI_SCK_0_0_PIN, AVR32_SPI_SCK_0_0_FUNCTION },
00100
00101
00102 #elif BOARD == EVK1105
00103 { AVR32_SPI0_NPCS_0_0_PIN, AVR32_SPI0_NPCS_0_0_FUNCTION },
00104 #if SPI_CS == 1
00105 { AVR32_SPI0_NPCS_1_0_PIN, AVR32_SPI0_NPCS_1_0_FUNCTION },
00106 #elif SPI_CS == 2
00107 { AVR32_SPI0_NPCS_2_0_PIN, AVR32_SPI0_NPCS_2_0_FUNCTION },
00108 #endif
00109 { AVR32_SPI0_MISO_0_0_PIN, AVR32_SPI0_MISO_0_0_FUNCTION },
00110 { AVR32_SPI0_MOSI_0_0_PIN, AVR32_SPI0_MOSI_0_0_FUNCTION },
00111 { AVR32_SPI0_SCK_0_0_PIN, AVR32_SPI0_SCK_0_0_FUNCTION },
00112 #else
00113 #error
00114 #endif
00115 };
00116 U32 i;
00117
00118 #ifndef WITH_NO_DMA
00119 volatile avr32_pdca_channel_t *pdca_tx = &AVR32_PDCA.channel[0];
00120 volatile avr32_pdca_channel_t *pdca_rx = &AVR32_PDCA.channel[1];
00121 #endif
00122
00123 #ifdef USE_POLL
00124 *flags = SPI_FLAG_POLL;
00125 #else
00126 *flags = 0;
00127 #endif
00128
00129 gpio_enable_module(GPIO_MAP, ARRAY_SIZE(GPIO_MAP));
00130
00131 for (i = 0; i < ARRAY_SIZE(GPIO_MAP); i++)
00132 gpio_enable_pin_pull_up(GPIO_MAP[i].pin);
00133
00134
00135 gpio_enable_gpio_pin(GPIO_IRQ_PIN);
00136 gpio_enable_pin_pull_up(GPIO_IRQ_PIN);
00137
00138
00139 Assert(pm->pbamask & (1 << 5));
00140
00141
00142 Assert(pm->pbamask & (1 << 1));
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 INTC_register_interrupt(&avr32_irq_handler, GPIO_IRQ, AVR32_INTC_INT0);
00153
00154 #ifndef WITH_NO_DMA
00155 INTC_register_interrupt(&avr32_irq_handler, AVR32_PDCA_IRQ_0,
00156 AVR32_INTC_INT0);
00157 INTC_register_interrupt(&avr32_irq_handler, AVR32_PDCA_IRQ_1,
00158 AVR32_INTC_INT0);
00159 pdca_tx->IER.terr = 1;
00160 pdca_rx->IER.terr = 1;
00161 #endif
00162 }
00163
00164 void platform_reset(void)
00165 {
00166 volatile avr32_spi_t *spi = &AVR32_SPI;
00167 #if SPI_CS == 1
00168 volatile avr32_spi_csr1_t* CSR = &spi->CSR1;
00169 #elif SPI_CS == 2
00170 volatile avr32_spi_csr2_t* CSR = &spi->CSR2;
00171 #endif
00172
00173
00174 spi->CR.spidis = 1;
00175
00176
00177 spi->MR.mstr = 1;
00178
00179
00180 spi->MR.ps = 0;
00181 #if SPI_CS == 2
00182 spi->MR.pcs = 0x3;
00183 #elif SPI_CS == 1
00184 spi->MR.pcs = 0x1;
00185 #endif
00186
00187 CSR->scbr = 2;
00188
00189
00190 CSR->bits = 0x8;
00191
00192
00193
00194
00195 CSR->csaat = 1;
00196
00197
00198 CSR->cpol = 1;
00199
00200
00201 spi->CR.spien = 1;
00202 }
00203
00204 #ifndef WITH_NO_DMA
00205 static void dma_txrx(const U8* in, U8* out, U16 len)
00206 {
00207 volatile avr32_pdca_channel_t *pdca_tx = &AVR32_PDCA.channel[0];
00208 volatile avr32_pdca_channel_t *pdca_rx = &AVR32_PDCA.channel[1];
00209
00210
00211 pdca_tx->mar = (U32) in;
00212 pdca_tx->PSR.pid = AVR32_PDCA_PID_TX;
00213 pdca_tx->tcr = len / 2;
00214 pdca_tx->MR.size = 1;
00215 pdca_tx->IER.trc = 1;
00216
00217
00218 pdca_rx->mar = (U32) out;
00219 pdca_rx->PSR.pid = AVR32_PDCA_PID_RX;
00220 pdca_rx->tcr = len / 2;
00221 pdca_rx->MR.size = 1;
00222 pdca_rx->IER.trc = 1;
00223
00224
00225 pdca_rx->CR.ten = 1;
00226 pdca_tx->CR.ten = 1;
00227
00228
00229 while (!(pdca_tx->ISR.trc && pdca_rx->ISR.trc));
00230 }
00231 #endif
00232
00233
00234
00235
00236
00237 static void fifo_txrx(const U8 *in, U8* out, U16 len)
00238 {
00239 volatile avr32_spi_t *spi = &AVR32_SPI;
00240 UnionCPtr in_ptr;
00241 UnionPtr out_ptr;
00242 U32 sr;
00243
00244 Assert(len);
00245
00246 in_ptr.u8ptr = in;
00247 out_ptr.u8ptr = out;
00248
00249 while (len) {
00250 U16 rdr;
00251 union {
00252 avr32_spi_tdr_t TDR;
00253 U32 tdr;
00254 } reg = { { 0 } };
00255
00256 while (!spi->SR.tdre);
00257 while (!spi->SR.txempty);
00258
00259
00260 if (in_ptr.u8ptr) {
00261 reg.TDR.td |= (in_ptr.u8ptr[0] << 8) | in_ptr.u8ptr[1];
00262 in_ptr.u16ptr++;
00263 }
00264 else
00265 reg.TDR.td |= 0xffff;
00266
00267
00268 spi->tdr = reg.tdr;
00269
00270
00271 while (!spi->SR.rdrf);
00272
00273
00274 rdr = spi->RDR.rd;
00275 if (out_ptr.u8ptr) {
00276 out_ptr.u8ptr[0] = (rdr >> 8) & 0xff;
00277 out_ptr.u8ptr[1] = rdr & 0xff;
00278 out_ptr.u16ptr++;
00279 }
00280
00281
00282
00283
00284 if (len >= 2)
00285 len -= 2;
00286 else
00287 len = 0;
00288 }
00289
00290 sr = spi->sr;
00291 Assert(!(sr & AVR32_SPI_SR_OVRES_MASK));
00292 Assert(!(sr & AVR32_SPI_SR_MODF_MASK));
00293 }
00294
00295 void platform_txrx(const U8 *in, U8* out, U16 len)
00296 {
00297 #ifndef WITH_NO_DMA
00298 static uint8_t buf[MAX_BLOCK_LEN];
00299
00300
00301 if ((U32) in % 4 || (U32) out % 4 || len % 2) {
00302 fifo_txrx(in, out, len);
00303 } else {
00304 if (in == NULL) {
00305 memset(buf, 0xff, len);
00306 in = buf;
00307 } else if (out == NULL) {
00308 out = buf;
00309 }
00310 dma_txrx(in, out, len);
00311 }
00312 #else
00313 fifo_txrx(in, out, len);
00314 #endif
00315 }
00316
00317 void platform_spi_irq(U8 enable)
00318 {
00319 #ifdef USE_POLL
00320 return;
00321 #endif
00322
00323 if (enable)
00324 gpio_enable_pin_interrupt(GPIO_IRQ_PIN, GPIO_PIN_CHANGE);
00325 else
00326 gpio_disable_pin_interrupt(GPIO_IRQ_PIN);
00327 }
00328
00329 void platform_spi_cs(U8 enable)
00330 {
00331 volatile avr32_spi_t *spi = &AVR32_SPI;
00332
00333 if (enable)
00334 #if SPI_CS == 2
00335 spi->MR.pcs = 0x3;
00336 #elif SPI_CS == 1
00337 spi->MR.pcs = 0x1;
00338 #endif
00339 else
00340 spi->MR.pcs = 0xf;
00341 }
00342
00343 __attribute__((__interrupt__)) void avr32_irq_handler(void)
00344 {
00345 uint8_t irq_status = 0;
00346 #ifndef WITH_NO_DMA
00347 volatile avr32_pdca_channel_t *pdca_tx = &AVR32_PDCA.channel[0];
00348 volatile avr32_pdca_channel_t *pdca_rx = &AVR32_PDCA.channel[1];
00349 #endif
00350
00351 if (gpio_get_pin_interrupt_flag(GPIO_IRQ_PIN)) {
00352 gpio_clear_pin_interrupt_flag(GPIO_IRQ_PIN);
00353 irq_status |= SPI_IRQ_RX;
00354 }
00355 #ifndef WITH_NO_DMA
00356
00357
00358 if (pdca_tx->IMR.trc && pdca_tx->ISR.trc) {
00359 pdca_tx->IDR.trc = 1;
00360 pdca_tx->CR.tdis = 1;
00361 }
00362
00363
00364 if (pdca_rx->IMR.trc && pdca_rx->ISR.trc) {
00365 pdca_rx->IDR.trc = 1;
00366 pdca_rx->CR.tdis = 1;
00367 }
00368
00369 #if 0
00370
00371 if (pdca_tx->ISR.trc && pdca_rx->ISR.trc)
00372 irq_status |= SPI_IRQ_XFER_COMPLETE;
00373 #endif
00374
00375 #endif
00376 if (irq_status)
00377 spi_irq_handler(irq_status);
00378 }