picked changes from spi_rewrite

* up to 30c07a6ba53e45453ed766c6ffefd6cd0d606493
This commit is contained in:
Felix Ruess
2012-03-27 00:23:34 +02:00
parent eb230911d1
commit aa506c9110
12 changed files with 829 additions and 326 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ ap.CFLAGS += -DUSE_I2C2
else ifeq ($(BOARD), navgo)
include $(CFG_ROTORCRAFT)/spi.makefile
ap.CFLAGS += -DUSE_SPI_SLAVE0
ap.CFLAGS += -DSPI_NO_UNSELECT_SLAVE
ap.CFLAGS += -DUSE_SPI1
ap.CFLAGS += -DSPI_MASTER
ap.srcs += peripherals/mcp355x.c
endif
+47 -15
View File
@@ -207,27 +207,59 @@
///////////////////////////////////////////////////////////////////////////////
// Serial Peripheral Interface 1 (SPI1)
#define SPI1 ((spiRegs_t *)0xE0030000)
#define SPI1 ((sspRegs_t *)0xE0068000)
// SPI1 Registers
#define S1SPCR SPI1->cr /* Control Register */
#define S1SPSR SPI1->sr /* Status Register */
#define S1SPDR SPI1->dr /* Data Register */
#define S1SPCCR SPI1->ccr /* Clock Counter Register */
#define S1SPINT SPI1->flag /* Interrupt Flag Register */
//#define S1SPCR SPI1->cr /* Control Register */
//#define S1SPSR SPI1->sr /* Status Register */
//#define S1SPDR SPI1->dr /* Data Register */
//#define S1SPCCR SPI1->ccr /* Clock Counter Register */
//#define S1SPINT SPI1->flag /* Interrupt Flag Register */
/* S1SPINT bits definition */
#define SPI1IF 0
#define SSPCR0 (*(REG16*) 0xE0068000) /* Control Register 0 */
#define SSPCR1 (*(REG_8*) 0xE0068004) /* Control Register 1 */
#define SSPDR (*(REG16*) 0xE0068008) /* Data register */
#define SSPSR (*(REG_8*) 0xE006800C) /* Status register */
#define SSPCPSR (*(REG_8*) 0xE0068010) /* Clock prescale register */
#define SSPIMSC (*(REG_8*) 0xE0068014) /* Interrupt mask register */
#define SSPRIS (*(REG_8*) 0xE0068018) /* Raw interrupt status register */
#define SSPMIS (*(REG_8*) 0xE006801C) /* Masked interrupt status register */
#define SSPICR (*(REG_8*) 0xE0068020) /* Interrupt clear register */
#define SSPCR0 SPI1->cr0 /* Control Register 0 */
#define SSPCR1 SPI1->cr1 /* Control Register 1 */
#define SSPDR SPI1->dr /* Data register */
#define SSPSR SPI1->sr /* Status register */
#define SSPCPSR SPI1->cpsr /* Clock prescale register */
#define SSPIMSC SPI1->imsc /* Interrupt mask register */
#define SSPRIS SPI1->ris /* Raw interrupt status register */
#define SSPMIS SPI1->mis /* Masked interrupt status register */
#define SSPICR SPI1->icr /* Interrupt clear register */
//#define SSPCR0 (*(REG16*) 0xE0068000) /* Control Register 0 */
//#define SSPCR1 (*(REG_8*) 0xE0068004) /* Control Register 1 */
//#define SSPDR (*(REG16*) 0xE0068008) /* Data register */
//#define SSPSR (*(REG_8*) 0xE006800C) /* Status register */
//#define SSPCPSR (*(REG_8*) 0xE0068010) /* Clock prescale register */
//#define SSPIMSC (*(REG_8*) 0xE0068014) /* Interrupt mask register */
//#define SSPRIS (*(REG_8*) 0xE0068018) /* Raw interrupt status register */
//#define SSPMIS (*(REG_8*) 0xE006801C) /* Masked interrupt status register */
//#define SSPICR (*(REG_8*) 0xE0068020) /* Interrupt clear register */
/* SSPCR0 bits definition */
#define DSS 0
#define FRF 4
#define CPOL 6
#define CPHA 7
#define SCR 8
/* SSPDSS values definition */
#define DSS_VAL4 0x3
#define DSS_VAL5 0x4
#define DSS_VAL6 0x5
#define DSS_VAL7 0x6
#define DSS_VAL8 0x7
#define DSS_VAL9 0x8
#define DSS_VAL10 0x9
#define DSS_VAL11 0xA
#define DSS_VAL12 0xB
#define DSS_VAL13 0XC
#define DSS_VAL14 0xD
#define DSS_VAL15 0xE
#define DSS_VAL16 0xF
/* SSPCR1 bits definition */
#define LBM 0
+23
View File
@@ -35,4 +35,27 @@ typedef struct
REG_8 _pad7[3];
} spiRegs_t;
// Serial Serial Port Registers (SSP/SPI)
typedef struct
{
REG_8 cr0; // Control Register 0
REG_8 _pad0[3];
REG_8 cr1; // Control Register 1
REG_8 _pad1[3];
REG_8 dr; // Data Register
REG_8 _pad2[3];
REG_8 sr; // Status Register
REG_8 _pad3[3];
REG_8 cpsr; // Clock Prescale Register
REG_8 _pad4[3];
REG_8 imsc; // Interrupt Mask Set and Clear Register
REG_8 _pad5[3];
REG_8 ris; // Raw Interrupt Status Register
REG_8 _pad6[3];
REG_8 mis; // Masked Interrupt Status Register
REG_8 _pad7[3];
REG_8 icr; // Interrupt Clear Register
REG_8 _pad8[3];
} sspRegs_t;
#endif
File diff suppressed because it is too large Load Diff
+8 -144
View File
@@ -32,89 +32,19 @@
#include "LPC21xx.h"
#include BOARD_CONFIG
extern volatile uint8_t spi_tx_idx;
extern volatile uint8_t spi_rx_idx;
#define SpiInitBuf() { \
spi_rx_idx = 0; \
spi_tx_idx = 0; \
spi_message_received = FALSE; \
SpiTransmit(); /* fill fifo */ \
}
#define SpiTransmit() { \
while (spi_tx_idx < spi_buffer_length \
&& bit_is_set(SSPSR, TNF)) { \
SpiSend(spi_buffer_output[spi_tx_idx]); \
spi_tx_idx++; \
} \
if (spi_tx_idx == spi_buffer_length) \
SpiDisableTxi(); \
}
// SSP is on SPI1 on lpc
#if defined USE_SSP & !USE_SPI1
#define USE_SP11 1
// TODO other defines ?
#endif
#define SpiReceive() { \
while (bit_is_set(SSPSR, RNE)) { \
if (spi_rx_idx < spi_buffer_length) { \
SpiRead(spi_buffer_input[spi_rx_idx]) \
spi_rx_idx++; \
} \
else { \
uint8_t foo; \
SpiRead(foo); \
} \
} \
}
#define SpiEnable() { \
SetBit(SSPCR1, SSE); \
}
#define SpiDisable() { \
ClearBit(SSPCR1, SSE); \
}
#define SpiEnableRti() { \
SetBit(SSPIMSC, RTIM); \
}
#define SpiDisableRti() { \
ClearBit(SSPIMSC, RTIM); \
}
#define SpiClearRti() { \
SetBit(SSPICR, RTIC); \
}
#define SpiEnableTxi() { \
SetBit(SSPIMSC, TXIM); \
}
#define SpiDisableTxi() { \
ClearBit(SSPIMSC, TXIM); \
}
#define SpiEnableRxi() { \
SetBit(SSPIMSC, RXIM); \
}
#define SpiDisableRxi() { \
ClearBit(SSPIMSC, RXIM); \
}
#define SpiSend(a) { \
SSPDR = a; \
}
#define SpiRead(a) { \
a = SSPDR; \
}
#ifdef SPI_SLAVE
#define SpiStart() { \
SpiEnable(); \
SpiInitBuf(); \
SpiEnableTxi(); /* enable tx fifo half empty interrupt */ \
}
extern volatile uint8_t spi_tx_idx;
extern volatile uint8_t spi_rx_idx;
#endif /* SPI_SLAVE */
@@ -123,73 +53,7 @@ extern volatile uint8_t spi_rx_idx;
#ifdef SPI_MASTER
/* !!!!!!!!!!!!! Code for one single slave at a time !!!!!!!!!!!!!!!!! */
#if defined SPI_SELECT_SLAVE1_PIN && defined SPI_SELECT_SLAVE0_PIN
#error "SPI: one single slave, please"
#endif
#define SpiStart() { \
SpiEnable(); \
SpiInitBuf(); \
SpiEnableTxi(); /* enable tx fifo half empty interrupt */ \
}
/*
* Slave0 select : P0.20 PINSEL1 00 << 8
* Slave1 select : P1.20
*
*/
#define SPI_SELECT_SLAVE_IO__(port, reg) IO ## port ## reg
#define SPI_SELECT_SLAVE_IO_(port, reg) SPI_SELECT_SLAVE_IO__(port, reg)
#define SPI_SELECT_SLAVE0_IODIR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, DIR)
#define SPI_SELECT_SLAVE0_IOCLR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, CLR)
#define SPI_SELECT_SLAVE0_IOSET SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, SET)
#define SPI_SELECT_SLAVE1_IODIR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, DIR)
#define SPI_SELECT_SLAVE1_IOCLR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, CLR)
#define SPI_SELECT_SLAVE1_IOSET SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, SET)
#define SpiSelectSlave0() { \
spi_cur_slave = SPI_SLAVE0; \
SetBit(SPI_SELECT_SLAVE0_IOCLR, SPI_SELECT_SLAVE0_PIN); \
}
#define SpiUnselectSlave0() { \
spi_cur_slave = SPI_NONE; \
SetBit(SPI_SELECT_SLAVE0_IOSET, SPI_SELECT_SLAVE0_PIN); \
}
#define SpiSelectSlave1() { \
spi_cur_slave = SPI_SLAVE1; \
SetBit(SPI_SELECT_SLAVE1_IOCLR, SPI_SELECT_SLAVE1_PIN); \
}
#define SpiUnselectSlave1() { \
spi_cur_slave = SPI_NONE; \
SetBit(SPI_SELECT_SLAVE1_IOSET, SPI_SELECT_SLAVE1_PIN); \
}
#ifdef SPI_SELECT_SLAVE0_PIN
#define SpiUnselectCurrentSlave() SpiUnselectSlave0()
#endif
#ifdef SPI_SELECT_SLAVE1_PIN
#define SpiUnselectCurrentSlave() SpiUnselectSlave1()
#endif
#endif /* SPI_MASTER */
#define SpiSetCPOL() (SSPCR0 |= _BV(6))
#define SpiClrCPOL() (SSPCR0 &= ~(_BV(6)))
#define SpiSetCPHA() (SSPCR0 |= _BV(7))
#define SpiClrCPHA() (SSPCR0 &= ~(_BV(7)))
#endif /* SPI_ARCH_H */
+112 -28
View File
@@ -1,4 +1,3 @@
#include "subsystems/imu.h"
#include <libopencm3/stm32/nvic.h>
#include <libopencm3/stm32/f1/gpio.h>
@@ -9,9 +8,62 @@
#include "mcu_periph/spi.h"
struct spi_transaction* slave0;
// SPI2 Slave Selection
#define Spi2Slave0Unselect() GPIO_BSRR(GPIOB) = GPIO12
#define Spi2Slave0Select() GPIO_BRR(GPIOB) = GPIO12
#define SPI2_SLAVE0_PORT GPIOB
#define SPI2_SLAVE0_PIN GPIO12
#define SPI2_SLAVE1_PORT GPIOB
#define SPI2_SLAVE1_PIN GPIO5
#define SPI2_SLAVE2_PORT GPIOB
#define SPI2_SLAVE2_PIN GPIO3
static inline void Spi2SlaveUnselect(uint8_t slave)
{
switch(slave) {
case 0:
GPIO_BSRR(SPI2_SLAVE0_PORT) = SPI2_SLAVE0_PIN;
break;
#if USE_SPI2_SLAVE1
case 1:
GPIO_BSRR(SPI2_SLAVE1_PORT) = SPI2_SLAVE1_PIN;
break;
#endif //USE_SPI2_SLAVE1
#if USE_SPI2_SLAVE2
case 2:
GPIO_BSRR(SPI2_SLAVE2_PORT) = SPI2_SLAVE2_PIN;
break;
#endif //USE_SPI2_SLAVE2
default:
break;
}
}
static inline void Spi2SlaveSelect(uint8_t slave)
{
switch(slave) {
case 0:
GPIO_BRR(SPI2_SLAVE0_PORT) = SPI2_SLAVE0_PIN;
break;
#if USE_SPI2_SLAVE1
case 1:
GPIO_BRR(SPI2_SLAVE1_PORT) = SPI2_SLAVE1_PIN;
break;
#endif //USE_SPI2_SLAVE1
#if USE_SPI2_SLAVE2
case 2:
GPIO_BRR(SPI2_SLAVE2_PORT) = SPI2_SLAVE2_PIN;
break;
#endif //USE_SPI2_SLAVE2
default:
break;
}
}
// spi dma end of rx handler
// XXX: should be provided by libopencm3?
@@ -72,41 +124,40 @@ void spi_init(void) {
// SLAVE 0
// set accel slave select as output and assert it ( on PB12)
Spi2Slave0Unselect();
Spi2SlaveUnselect(0);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
GPIO_CNF_OUTPUT_PUSHPULL, SPI2_SLAVE0_PIN);
// SLAVE 1
Spi2SlaveUnselect(1);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, SPI2_SLAVE1_PIN);
// SLAVE 2
Spi2SlaveUnselect(1);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, SPI2_SLAVE2_PIN);
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //Slave2 is on JTDO pin, so disable JTAG DP
spi2.trans_insert_idx = 0;
spi2.trans_extract_idx = 0;
spi2.status = SPIIdle;
spi_arch_int_enable();
}
/*
void adxl345_write_to_reg(uint8_t addr, uint8_t val) {
Adxl345Select();
SPI_I2S_SendData(SPI2, addr);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, val);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
Adxl345Unselect();
}
void spi_clear_rx_buf(void) {
uint8_t __attribute__ ((unused)) ret = SPI_I2S_ReceiveData(SPI2);
}
*/
struct spi_transaction* slave0;
void spi_rw(struct spi_transaction * _trans)
{
// Store local copy to notify of the results
slave0 = _trans;
slave0->status = SPITransRunning;
Spi2Slave0Select();
spi2.status = SPIRunning;
Spi2SlaveSelect(slave0->slave_idx);
// SPI2_Rx_DMA_Channel configuration ------------------------------------
@@ -151,11 +202,37 @@ void spi_rw(struct spi_transaction * _trans)
}
bool_t spi_submit(struct spi_periph* p, struct spi_transaction* t)
{
uint8_t idx;
idx = p->trans_insert_idx + 1;
if (idx >= SPI_TRANSACTION_QUEUE_LEN) idx = 0;
if (idx == p->trans_extract_idx) {
t->status = SPITransFailed;
return FALSE; /* queue full */
}
t->status = SPITransPending;
// FIXME: still needed?
//*(t->ready) = 0;
//Disable interrupts to avoid race conflict with end of DMA transfer interrupt
__disable_irq();
p->trans[p->trans_insert_idx] = t;
p->trans_insert_idx = idx;
/* if peripheral is idle, start the transaction */
if (p->status == SPIIdle) {
spi_rw(p->trans[p->trans_extract_idx]);
}
__enable_irq();
return TRUE;
}
// Accel end of DMA transferred
void dma1_channel4_isr(void)
{
Spi2Slave0Unselect();
Spi2SlaveUnselect(spi2.trans[spi2.trans_extract_idx]->slave_idx);
if ((DMA1_ISR & DMA_ISR_TCIF4) != 0) {
// clear int pending bit
@@ -164,7 +241,6 @@ void dma1_channel4_isr(void)
// mark as available
spi_message_received = TRUE;
}
// disable DMA Channel
dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL4);
@@ -178,7 +254,15 @@ void dma1_channel4_isr(void)
slave0->status = SPITransSuccess;
*(slave0->ready) = 1;
spi2.trans_extract_idx++;
// Check if there is another pending SPI transaction
if (spi2.trans_extract_idx >= SPI_TRANSACTION_QUEUE_LEN)
spi2.trans_extract_idx = 0;
if (spi2.trans_extract_idx == spi2.trans_insert_idx)
spi2.status = SPIIdle;
else
spi_rw(spi2.trans[spi2.trans_extract_idx]);
}
@@ -37,7 +37,6 @@ extern void spi_arch_int_disable(void);
extern void spi_clear_rx_buf(void);
void spi_rw(struct spi_transaction * _trans);
/*
//////////
+2 -2
View File
@@ -51,8 +51,8 @@ extern bool_t link_mcu_received;
extern void link_mcu_event_task( void );
#if defined MCU_SPI_LINK && ! defined USE_SPI
#define USE_SPI
#if defined MCU_SPI_LINK && !USE_SPI
#define USE_SPI 1
#endif
+12 -3
View File
@@ -46,7 +46,7 @@
#ifdef USE_USB_SERIAL
#include "mcu_periph/usb_serial.h"
#endif
#ifdef USE_SPI
#if USE_SPI0 || USE_SPI1 || USE_SPI2
#include "mcu_periph/spi.h"
#endif
#ifdef USE_DAC
@@ -100,8 +100,17 @@ void mcu_init(void) {
#ifdef USE_USB_SERIAL
VCOM_init();
#endif
#ifdef USE_SPI
spi_init();
#if USE_SPI0
spi0_init();
#endif
#if USE_SPI1
spi1_init();
#endif
#if USE_SPI2
spi2_init();
#endif
#if USE_SPI0 || USE_SPI1 || USE_SPI2
spi_init_slaves();
#endif
#ifdef USE_DAC
dac_init();
+46 -6
View File
@@ -25,14 +25,54 @@
#include "std.h"
#include "mcu_periph/spi.h"
#ifdef SPI_MASTER
#if USE_SPI0
struct spi_periph spi0;
void spi0_init(void) {
spi_init(&spi0);
spi0_arch_init();
}
#endif
#if USE_SPI1
struct spi_periph spi1;
void spi1_init(void) {
spi_init(&spi1);
spi1_arch_init();
}
#endif
#if USE_SPI2
struct spi_periph spi2;
void spi2_init(void) {
spi_init(&spi2);
spi2_arch_init();
}
#endif
void spi_init(struct spi_periph* p) {
p->trans_insert_idx = 0;
p->trans_extract_idx = 0;
p->status = SPIIdle;
}
#endif /* SPI_MASTER */
#ifdef SPI_SLAVE
uint8_t* spi_buffer_input;
uint8_t* spi_buffer_output;
uint8_t spi_buffer_length;
volatile bool_t spi_message_received;
#ifdef SPI_MASTER
volatile uint8_t spi_cur_slave;
uint8_t spi_nb_ovrn;
#endif /* SPI_MASTER */
#endif
+170 -22
View File
@@ -29,27 +29,188 @@
#ifndef SPI_H
#define SPI_H
#ifdef USE_SPI
//#if USE_SPI
#include "std.h"
#include "mcu_periph/spi_arch.h"
// FIXME how to use this properly ?
enum SPIMode {
SPIMaster,
SPISlave
};
/** SPI slave selection behavior.
* SelectUnselect: slave is selected before transaction and unselected after
* Select: slave is selected before transaction but not unselected
* Unselect: slave is not selected but unselected after transaction
* NoSelect: slave is not selected nor unselected
*
* Default operation should be SelectUnselected, but some peripherals
* might need some special control
* Use non-default control only if you know what you're doing
*/
enum SPISlaveSelect {
SPISelectUnselect,
SPISelect,
SPIUnselect,
SPINoSelect
};
/** SPI clock phase control.
* control when data are sampled (rising or falling edge of clock)
* depending of the clock polarity
* Mode 0: data sampled on first clock edge
* Mode 1: data sampled on second clock edge
*/
enum SPIClockPhase {
SPICPHA_Mode0,
SPICPHA_Mode1
};
/** SPI clock polarity control.
* Mode 0: clock idle low
* Mode 1: clock idle high
*/
enum SPIClockPolarity {
SPICPOL_Mode0,
SPICPOL_Mode1
};
/** SPI Data size transfer.
*/
enum SPIDataSizeSelect {
DSS8bit,
DSS16bit
};
/** SPI transaction status.
*/
enum SPITransactionStatus {
SPITransPending,
SPITransRunning,
SPITransSuccess,
SPITransFailed
SPITransFailed,
SPITransDone
};
/** SPI peripheral status.
*/
enum SPIStatus {
SPIIdle,
SPIRunning
};
#ifndef SPI_BUF_LEN
#define SPI_BUF_LEN 32
#endif
struct spi_transaction {
volatile uint8_t* mosi_buf;
volatile uint8_t* miso_buf;
volatile uint8_t* ready;
volatile uint8_t input_buf[SPI_BUF_LEN];
volatile uint8_t output_buf[SPI_BUF_LEN];
volatile uint8_t* ready; // FIXME what is the difference with status ?
uint8_t length;
uint8_t slave_idx;
enum SPISlaveSelect select;
enum SPIClockPolarity cpol;
enum SPIClockPhase cpha;
enum SPIDataSizeSelect dss; // Architecture dependant options (LPC21) ?
volatile enum SPITransactionStatus status;
};
#include "mcu_periph/spi_arch.h"
#ifndef SPI_TRANSACTION_QUEUE_LEN
#define SPI_TRANSACTION_QUEUE_LEN 8
#endif
struct spi_periph {
/* circular buffer holding transactions */
struct spi_transaction* trans[SPI_TRANSACTION_QUEUE_LEN];
uint8_t trans_insert_idx;
uint8_t trans_extract_idx;
/* internal state of the peripheral */
volatile enum SPIStatus status;
volatile uint8_t tx_idx_buf;
volatile uint8_t rx_idx_buf;
void* reg_addr;
enum SPIMode mode;
};
#ifdef SPI_MASTER
#define SPI_SLAVE0 0
#define SPI_SLAVE1 1
#define SPI_SLAVE2 2
//extern uint8_t spi_nb_ovrn; //TODO SPI error struct
#if USE_SPI0
extern struct spi_periph spi0;
extern void spi0_init(void);
/** Architecture dependant SPI0 initialization.
* Must be implemented by underlying architecture
*/
extern void spi0_arch_init(void);
#endif
#if USE_SPI1
extern struct spi_periph spi1;
extern void spi1_init(void);
/** Architecture dependant SPI1 initialization.
* Must be implemented by underlying architecture
*/
extern void spi1_arch_init(void);
#endif
#if USE_SPI2
extern struct spi_periph spi2;
extern void spi2_init(void);
/** Architecture dependant SPI2 initialization.
* Must be implemented by underlying architecture
*/
extern void spi2_arch_init(void);
#endif
/** Initialize a spi peripheral.
* @param p spi peripheral to be configured
*/
extern void spi_init(struct spi_periph* p);
/** Initialize all used slaves and uselect them.
*/
extern void spi_init_slaves(void);
/** Submit a spi transaction.
* Must be implemented by the underlying architecture
* @param p spi peripheral to be used
* @param t spi transaction
* @return return true if insertion to the transaction queue succed
*/
extern bool_t spi_submit(struct spi_periph* p, struct spi_transaction* t);
/** Select a slave.
* @param slave slave id
*/
void spi_slave_select(uint8_t slave);
/** Unselect a slave.
* @param slave slave id
*/
void spi_slave_unselect(uint8_t slave);
#endif /* SPI_MASTER */
#ifdef SPI_SLAVE
extern uint8_t* spi_buffer_input;
extern uint8_t* spi_buffer_output;
@@ -57,23 +218,10 @@ extern uint8_t spi_buffer_length;
extern volatile bool_t spi_message_received;
void spi_init(void);
void spi_slave_init(void);
#ifdef SPI_MASTER
#endif
#define SPI_NONE 0
#define SPI_SLAVE0 1
#define SPI_SLAVE1 2
#define SPI_SLAVE2 3
extern volatile uint8_t spi_cur_slave;
extern uint8_t spi_nb_ovrn;
#define SpiCheckAvailable() (spi_cur_slave == SPI_NONE)
#define SpiOverRun() {spi_nb_ovrn++;}
#endif /* SPI_MASTER */
#endif /* USE_SPI */
//#endif /* USE_SPI */
#endif /* SPI_H */
+20 -14
View File
@@ -28,34 +28,40 @@
bool_t mcp355x_data_available;
int32_t mcp355x_data;
uint8_t mcp355x_spi_buf[4];
struct spi_transaction mcp355x_spi_trans;
void mcp355x_init(void) {
mcp355x_data_available = FALSE;
mcp355x_data = 0;
SpiClrCPOL();
SpiClrCPHA();
mcp355x_spi_trans.length = 4;
mcp355x_spi_trans.slave_idx = SPI_SLAVE0;
mcp355x_spi_trans.select = SPISelect;
mcp355x_spi_trans.cpol = SPICPOL_Mode0;
mcp355x_spi_trans.cpha = SPICPHA_Mode0;
mcp355x_spi_trans.dss = DSS8bit;
}
void mcp355x_read(void) {
spi_buffer_length = 4;
spi_buffer_input = mcp355x_spi_buf;
//SpiSelectSlave0();
SpiStart();
spi_submit(&spi1, &mcp355x_spi_trans);
}
void mcp355x_event(void) {
if (spi_message_received) {
spi_message_received = FALSE;
if ((mcp355x_spi_buf[0]>>4) == 0) {
if (mcp355x_spi_trans.status == SPITransSuccess) {
if ((mcp355x_spi_trans.input_buf[0]>>4) == 0) {
mcp355x_data = (int32_t)(
((uint32_t)mcp355x_spi_buf[0]<<17) |
((uint32_t)mcp355x_spi_buf[1]<<9) |
((uint32_t)mcp355x_spi_buf[2]<<1) |
(mcp355x_spi_buf[3]>>7));
((uint32_t)mcp355x_spi_trans.input_buf[0]<<17) |
((uint32_t)mcp355x_spi_trans.input_buf[1]<<9) |
((uint32_t)mcp355x_spi_trans.input_buf[2]<<1) |
(mcp355x_spi_trans.input_buf[3]>>7));
mcp355x_data_available = TRUE;
}
mcp355x_spi_trans.status = SPITransDone;
}
if (mcp355x_spi_trans.status == SPITransFailed) {
mcp355x_spi_trans.status = SPITransDone;
}
}