00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <aversive.h>
00025 #include <aversive/parts.h>
00026 #include <aversive/error.h>
00027
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include <spi.h>
00032 #include <spi_config.h>
00033
00034
00035 typedef struct _ss_pin {
00036 volatile uint8_t *port;
00037 uint8_t bitnum;
00038 } ss_pin_t;
00039
00040
00041
00042 static volatile ss_pin_t g_ss_lines[SPI_MAX_SLAVES+1];
00043 static volatile uint8_t g_ss_number;
00044 static volatile spi_mode_t g_spi_mode;
00045 static volatile uint8_t g_slave_selected;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 int8_t spi_register_ss_line(volatile uint8_t *port, uint8_t bitnum)
00056 {
00057 DEBUG(E_SPI, "Trying to register new SS line: port 0x%x, bitnum %d", port, bitnum);
00058
00059 if (g_ss_number >= SPI_MAX_SLAVES+1)
00060 return -1;
00061
00062 g_ss_lines[g_ss_number].port = port;
00063 g_ss_lines[g_ss_number].bitnum = bitnum;
00064 *(port-1) |= _BV(bitnum);
00065
00066 *port |= (_BV(bitnum));
00067
00068 NOTICE(E_SPI, "New Slave Line registered: %d", g_ss_number);
00069
00070 return g_ss_number++;
00071 }
00072
00073
00074
00075
00076
00077 inline void spi_set_data_order(uint8_t order)
00078 {
00079 if (order == SPI_LSB_FIRST)
00080 SPCR |= _BV(DORD);
00081 else
00082 SPCR &= ~(_BV(DORD));
00083 }
00084
00085
00086
00087
00088 inline uint8_t spi_get_data_order(void)
00089 {
00090 if (SPCR & _BV(DORD))
00091 return SPI_LSB_FIRST;
00092 return SPI_MSB_FIRST;
00093 }
00094
00095
00096
00097
00098
00099 void spi_init(spi_mode_t mode, spi_format_t format, spi_clk_rate_t clk_rate)
00100 {
00101 NOTICE(E_SPI, "Init SPI: mode %d, format %d, clk_rate %d",
00102 mode, format, clk_rate);
00103
00104
00105 DDR(SCK_PORT) |= _BV(SCK_BIT);
00106 DDR(MOSI_PORT) |= _BV(MOSI_BIT);
00107 DDR(MISO_PORT) &= ~(_BV(MISO_BIT));
00108
00109
00110
00111 g_ss_number = 0;
00112 g_slave_selected = FALSE;
00113
00114
00115 #ifdef PRR0
00116 PRR0 &= ~(_BV(PRSPI));
00117 #endif
00118 SPCR = 0;
00119 SPSR = 0;
00120
00121 SPCR |= _BV(MSTR);
00122 SPCR |= (uint8_t)format;
00123
00124
00125 if (clk_rate & 0x01)
00126 SPR0_REG |= _BV(SPR0);
00127 else
00128 SPR0_REG &= ~(_BV(SPR0));
00129 if (clk_rate & 0x02)
00130 SPR1_REG |= _BV(SPR1);
00131 else
00132 SPR1_REG &= ~(_BV(SPR1));
00133 if (clk_rate & 0x10)
00134 SPI2X_REG |= _BV(SPI2X);
00135 else
00136 SPI2X_REG &= ~(_BV(SPI2X));
00137
00138 SPCR |= _BV(SPE);
00139
00140 g_spi_mode = SPI_MODE_MASTER;
00141 NOTICE(E_SPI, "Init done");
00142 }
00143
00144
00145
00146
00147 inline spi_mode_t spi_get_mode(void)
00148 {
00149 return g_spi_mode;
00150 }
00151
00152
00153
00154
00155
00156 uint8_t spi_send_and_receive_byte(uint8_t byte)
00157 {
00158
00159
00160 SPDR = byte;
00161
00162
00163
00164 while(!(SPSR & (1<<SPIF)))
00165 ;
00166
00167 return SPDR;
00168 }
00169
00170
00171
00172
00173 inline void spi_send_byte(uint8_t byte)
00174 {
00175 spi_send_and_receive_byte(byte);
00176 }
00177
00178
00179
00180
00181 uint8_t spi_receive_byte(void)
00182 {
00183 return spi_send_and_receive_byte(0x00);
00184 }
00185
00186
00187
00188
00189 uint8_t spi_slave_select(uint8_t slave)
00190 {
00191 if (g_slave_selected) {
00192 ERROR(E_SPI, "A slave is already selected !");
00193 return EBUSY;
00194 }
00195
00196 *(g_ss_lines[slave].port) &= ~(_BV(g_ss_lines[slave].bitnum));
00197 g_slave_selected = TRUE;
00198 return ESUCCESS;
00199 }
00200
00201
00202
00203
00204 void spi_slave_deselect(uint8_t slave)
00205 {
00206 *(g_ss_lines[slave].port) |= (_BV(g_ss_lines[slave].bitnum));
00207 g_slave_selected = FALSE;
00208 }
00209
00210
00211
00212
00213 void spi_display_ss_lines(void)
00214 {
00215 uint8_t i;
00216 for (i = 0; i < g_ss_number; i++) {
00217 DEBUG(E_SPI, "SS%d: adr 0x%x bitnum %d value 0x%x",
00218 i,
00219 g_ss_lines[i].port,
00220 g_ss_lines[i].bitnum,
00221 *(g_ss_lines[i].port));
00222 }
00223 }