blob: de4186650bbc529402586aa949be23e60edc5bc0 [file] [log] [blame]
brians0ab60bb2013-01-31 02:21:51 +00001#include "stdio.h"
2#include "FreeRTOS.h"
3#include "spi.h"
4
5void spi_init (void) {
6 SC->PCONP |= PCONP_PCSPI;
7 SC->PCLKSEL0 |= 0x00010000;
8
9 // Hook up the interrupt
10 //NVIC_EnableIRQ(SPI_IRQn);
11
12 // SCK
13 PINCON->PINSEL0 &= 0x3fffffff;
14 PINCON->PINSEL0 |= 0xc0000000;
15
16 // SSEL, MISO, MOSI
17 // SSEL is GPIO, and needs to be done manually.
18 disable_gyro_csel();
19 GPIO0->FIODIR |= 0x00010000;
20 PINCON->PINSEL1 &= 0xffffffc0;
21 PINCON->PINSEL1 |= 0x0000003c;
22
23 // Master mode, 16 bits/frame, enable interrupts
24 SPI->SPCR = 0x000000a4;
25 // 13 clocks per cycle. This works out to a 7.7 mhz buss.
26 SPI->SPCCR = 0x0000000d;
27
28 // TODO(aschuh): Implement the gyro bring-up blocking first.
29 // Then use interrupts.
30 enable_gyro_csel();
31 printf("SPI Gyro Initial Response 0x%x %x\n", transfer_spi_bytes(0x2000), transfer_spi_bytes(0x0003));
32 disable_gyro_csel();
33}
34
35// TODO: DMA? SSP0? SSP0 should have a buffer, which would be very nice.
36uint16_t transfer_spi_bytes(uint16_t data) {
37 SPI->SPDR = (uint32_t)data;
38 while (!(SPI->SPSR & 0x80));
39 return SPI->SPDR;
40}
41
42void disable_gyro_csel (void) {
43 // Set the CSEL pin high to deselect it.
44 GPIO0->FIOSET = 0x00010000;
45}
46
47void enable_gyro_csel (void) {
48 // Clear the CSEL pin high to select it.
49 GPIO0->FIOCLR = 0x00010000;
50}
51
52void SPI_IRQHandler(void) {
53 int status = SPI->SPSR;
54 if (status & 0x80) {
55 // Transfer completed.
56 }
57
58 // Clear the interrupt?
59 SPI->SPINT = 0x00000001;
60}