#include <avr/io.h>
#include <avr/interrupt.h>
Go to the source code of this file.
Data Structures | |
struct | usidriverStatus_t |
Driver status bit structure. More... | |
Defines | |
#define | USI_OUT_REG PORTB |
USI port output register. | |
#define | USI_IN_REG PINE |
USI port input register. | |
#define | USI_DIR_REG DDRB |
USI port direction register. | |
#define | USI_CLOCK_PIN PB2 |
USI clock I/O pin. | |
#define | USI_DATAIN_PIN PB1 |
USI data input pin. | |
#define | USI_DATAOUT_PIN PB0 |
USI data output pin. | |
#define | TC0_PRESCALER_VALUE 256 |
Must be 1, 8, 64, 256 or 1024. | |
#define | TC0_COMPARE_VALUE 1 |
Must be 0 to 255. Minimum 31 with prescaler CLK/1. | |
#define | TC0_PS_SETTING (1<<CS02) |
Functions | |
ISR (SIG_USI_OVERFLOW) | |
Timer/Counter 0 Compare Match Interrupt handler. | |
void | spiX_initmaster (char spi_mode) |
Initialize USI as SPI master. | |
void | spiX_initslave (char spi_mode) |
Initialize USI as SPI slave. | |
char | spiX_put (unsigned char val) |
Put one byte on bus. | |
unsigned char | spiX_get (void) |
Get one byte from bus. | |
void | spiX_wait (void) |
Wait for transfer to complete. | |
Variables | |
unsigned char | storedUSIDR |
Data input register buffer. | |
struct usidriverStatus_t | spiX_status |
The driver status bits. |
Atmel Corporation
Definition in file spi_via_usi_driver.c.
#define TC0_COMPARE_VALUE 1 |
Must be 0 to 255. Minimum 31 with prescaler CLK/1.
Definition at line 46 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster().
#define TC0_PRESCALER_VALUE 256 |
Must be 1, 8, 64, 256 or 1024.
Definition at line 45 of file spi_via_usi_driver.c.
#define TC0_PS_SETTING (1<<CS02) |
Definition at line 60 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster().
#define USI_CLOCK_PIN PB2 |
USI clock I/O pin.
Definition at line 34 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster(), and spiX_initslave().
#define USI_DATAIN_PIN PB1 |
USI data input pin.
Definition at line 35 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster(), and spiX_initslave().
#define USI_DATAOUT_PIN PB0 |
USI data output pin.
Definition at line 36 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster(), and spiX_initslave().
#define USI_DIR_REG DDRB |
USI port direction register.
Definition at line 33 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster(), and spiX_initslave().
#define USI_IN_REG PINE |
USI port input register.
Definition at line 32 of file spi_via_usi_driver.c.
#define USI_OUT_REG PORTB |
USI port output register.
Definition at line 31 of file spi_via_usi_driver.c.
Referenced by spiX_initmaster(), and spiX_initslave().
ISR | ( | SIG_USI_OVERFLOW | ) |
Timer/Counter 0 Compare Match Interrupt handler.
This interrupt handler is only enabled when transferring data in master mode. It toggles the USI clock pin, i.e. two interrupts results in one clock period on the clock pin and for the USI counter.
USI Timer Overflow Interrupt handler. This handler disables the compare match interrupt if in master mode. When the USI counter overflows, a byte has been transferred, and we have to stop the timer tick. For all modes the USIDR contents are stored and flags are updated.
Definition at line 118 of file spi_via_usi_driver.c.
00119 { 00120 // Master must now disable the compare match interrupt 00121 // to prevent more USI counter clocks. 00122 if( spiX_status.masterMode == 1 ) { 00123 TIMSK &= ~(1<<OCIE0A); 00124 } 00125 00126 // Update flags and clear USI counter 00127 USISR = (1<<USIOIF); 00128 spiX_status.transferComplete = 1; 00129 00130 // Copy USIDR to buffer to prevent overwrite on next transfer. 00131 storedUSIDR = USIDR; 00132 }
unsigned char spiX_get | ( | void | ) |
Get one byte from bus.
This function only returns the previous stored USIDR value. The transfer complete flag is not checked. Use this function like you would read from the SPDR register in the native SPI module.
Definition at line 248 of file spi_via_usi_driver.c.
00249 { 00250 return storedUSIDR; 00251 }
void spiX_initmaster | ( | char | spi_mode | ) |
Initialize USI as SPI master.
This function sets up all pin directions and module configurations. Use this function initially or when changing from slave to master mode. Note that the stored USIDR value is cleared.
spi_mode | Required SPI mode, must be 0 or 1. |
Definition at line 144 of file spi_via_usi_driver.c.
00145 { 00146 // Configure port directions. 00147 USI_DIR_REG |= (1<<USI_DATAOUT_PIN) | (1<<USI_CLOCK_PIN); // Outputs. 00148 USI_DIR_REG &= ~(1<<USI_DATAIN_PIN); // Inputs. 00149 USI_OUT_REG |= (1<<USI_DATAIN_PIN); // Pull-ups. 00150 00151 // Configure USI to 3-wire master mode with overflow interrupt. 00152 USICR = (1<<USIOIE) | (1<<USIWM0) | 00153 (1<<USICS1) | (spi_mode<<USICS0) | 00154 (1<<USICLK); 00155 00156 // Enable 'Clear Timer on Compare match' and init prescaler. 00157 TCCR0A = TC0_PS_SETTING; 00158 00159 //TCCR0A = (1<<WGM01); 00160 00161 // Init Output Compare Register. 00162 OCR0A = TC0_COMPARE_VALUE; 00163 00164 // Init driver status register. 00165 spiX_status.masterMode = 1; 00166 spiX_status.transferComplete = 0; 00167 spiX_status.writeCollision = 0; 00168 00169 storedUSIDR = 0; 00170 }
void spiX_initslave | ( | char | spi_mode | ) |
Initialize USI as SPI slave.
This function sets up all pin directions and module configurations. Use this function initially or when changing from master to slave mode. Note that the stored USIDR value is cleared.
spi_mode | Required SPI mode, must be 0 or 1. |
Definition at line 182 of file spi_via_usi_driver.c.
00183 { 00184 // Configure port directions. 00185 USI_DIR_REG |= (1<<USI_DATAOUT_PIN); // Outputs. 00186 USI_DIR_REG &= ~(1<<USI_DATAIN_PIN) | (1<<USI_CLOCK_PIN); // Inputs. 00187 USI_OUT_REG |= (1<<USI_DATAIN_PIN) | (1<<USI_CLOCK_PIN); // Pull-ups. 00188 00189 // Configure USI to 3-wire slave mode with overflow interrupt. 00190 USICR = (1<<USIOIE) | (1<<USIWM0) | 00191 (1<<USICS1) | (spi_mode<<USICS0); 00192 00193 // Init driver status register. 00194 spiX_status.masterMode = 0; 00195 spiX_status.transferComplete = 0; 00196 spiX_status.writeCollision = 0; 00197 00198 storedUSIDR = 0; 00199 }
char spiX_put | ( | unsigned char | val | ) |
Put one byte on bus.
Use this function like you would write to the SPDR register in the native SPI module. Calling this function in master mode starts a transfer, while in slave mode, a byte will be prepared for the next transfer initiated by the master device. If a transfer is in progress, this function will set the write collision flag and return without altering the data registers.
Definition at line 213 of file spi_via_usi_driver.c.
00214 { 00215 // Check if transmission in progress, 00216 // i.e. USI counter unequal to zero. 00217 if( (USISR & 0x0F) != 0 ) { 00218 // Indicate write collision and return. 00219 spiX_status.writeCollision = 1; 00220 return 1; 00221 } 00222 00223 // Reinit flags. 00224 spiX_status.transferComplete = 0; 00225 spiX_status.writeCollision = 0; 00226 00227 // Put data in USI data register. 00228 USIDR = val; 00229 00230 // Master should now enable compare match interrupts. 00231 if( spiX_status.masterMode == 1 ) { 00232 TIFR |= (1<<OCF0A); // Clear compare match flag. 00233 TIMSK |= (1<<OCIE0A); // Enable compare match interrupt. 00234 } 00235 00236 if( spiX_status.writeCollision == 0 ) return 1; 00237 return 0; 00238 }
void spiX_wait | ( | void | ) |
Wait for transfer to complete.
This function waits until the transfer complete flag is set. Use this function like you would wait for the native SPI interrupt flag.
Definition at line 260 of file spi_via_usi_driver.c.
00261 { 00262 do {} while( spiX_status.transferComplete == 0 ); 00263 }
struct usidriverStatus_t spiX_status |
The driver status bits.
Definition at line 93 of file spi_via_usi_driver.c.
Referenced by ISR(), spiX_initmaster(), spiX_initslave(), spiX_put(), and spiX_wait().
unsigned char storedUSIDR |
Data input register buffer.
Incoming bytes are stored in this byte until the next transfer is complete. This byte can be used the same way as the SPI data register in the native SPI module, which means that the byte must be read before the next transfer completes and overwrites the current value.
Definition at line 76 of file spi_via_usi_driver.c.
Referenced by ISR(), spiX_get(), spiX_initmaster(), and spiX_initslave().