diff options
| author | Keith Packard <keithp@keithp.com> | 2013-08-28 22:52:58 -0600 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2013-08-28 22:52:58 -0600 | 
| commit | dcc51bb18985c24fa35bce0dd42ea3d847b960bf (patch) | |
| tree | 652c06c900b01b3c43f674e0f121109cc54b1120 /src/cc1111/ao_spi.c | |
| parent | 7c82acc1c1c5b7b4da7c7ecb3b2fd90140e4c703 (diff) | |
| parent | a73b02518fcbc9fc0807ed8e141d3a06e8ad8214 (diff) | |
Merge remote-tracking branch 'origin/telemini'
Signed-off-by: Keith Packard <keithp@keithp.com>
Conflicts:
	src/core/ao_telemetry.c
	src/core/ao_telemetry.h
Added both Mini and Metrum telemetry defines
Diffstat (limited to 'src/cc1111/ao_spi.c')
| -rw-r--r-- | src/cc1111/ao_spi.c | 257 | 
1 files changed, 159 insertions, 98 deletions
| diff --git a/src/cc1111/ao_spi.c b/src/cc1111/ao_spi.c index cdef6bda..fb08f3f5 100644 --- a/src/cc1111/ao_spi.c +++ b/src/cc1111/ao_spi.c @@ -18,10 +18,6 @@  #include "ao.h"  /* Default pin usage for existing Altus Metrum devices */ -#if !HAS_SPI_0 && !HAS_SPI_1 -#define HAS_SPI_0	1 -#define SPI_0_ALT_2	1 -#endif  #ifndef SPI_CONST  #define SPI_CONST	0xff @@ -61,62 +57,107 @@   */  #if HAS_SPI_0 -#define SPI_CSR		U0CSR -#define SPI_BUF		U0DBUFXADDR -#define SPI_BAUD	U0BAUD -#define SPI_GCR		U0GCR -#define SPI_CFG_MASK	PERCFG_U0CFG_ALT_MASK -#define SPI_DMA_TX	DMA_CFG0_TRIGGER_UTX0 -#define SPI_DMA_RX	DMA_CFG0_TRIGGER_URX0 +#define SPI_BUF_0	&U0DBUFXADDR +#define SPI_CSR_0	U0CSR +#define SPI_BAUD_0	U0BAUD +#define SPI_GCR_0	U0GCR +#define SPI_CFG_MASK_0	PERCFG_U0CFG_ALT_MASK +#define SPI_DMA_TX_0	DMA_CFG0_TRIGGER_UTX0 +#define SPI_DMA_RX_0	DMA_CFG0_TRIGGER_URX0  #if SPI_0_ALT_1 -#define SPI_CFG		PERCFG_U0CFG_ALT_1 -#define SPI_SEL		P0SEL -#define SPI_BITS	(1 << 3) | (1 << 2) | (1 << 5) -#define SPI_CSS_BIT	(1 << 4) +#define SPI_CFG_0	PERCFG_U0CFG_ALT_1 +#define SPI_SEL_0	P0SEL +#define SPI_BITS_0	(1 << 3) | (1 << 2) | (1 << 5) +#define SPI_CSS_BIT_0	(1 << 4)  #endif  #if SPI_0_ALT_2 -#define SPI_CFG		PERCFG_U0CFG_ALT_2 -#define SPI_SEL		P1SEL -#define SPI_PRI		P2SEL_PRI3P1_USART0 -#define SPI_BITS	(1 << 5) | (1 << 4) | (1 << 3) -#define SPI_CSS_BIT	(1 << 2) +#define SPI_CFG_0	PERCFG_U0CFG_ALT_2 +#define SPI_SEL_0	P1SEL +#define SPI_PRI_0	P2SEL_PRI3P1_USART0 +#define SPI_BITS_0	(1 << 5) | (1 << 4) | (1 << 3) +#define SPI_CSS_BIT_0	(1 << 2)  #endif  #endif  #if HAS_SPI_1 -#define SPI_CSR		U1CSR -#define SPI_BUF		U1DBUFXADDR -#define SPI_BAUD	U1BAUD -#define SPI_GCR		U1GCR -#define SPI_CFG_MASK	PERCFG_U1CFG_ALT_MASK -#define SPI_DMA_TX	DMA_CFG0_TRIGGER_UTX1 -#define SPI_DMA_RX	DMA_CFG0_TRIGGER_URX1 +#define SPI_BUF_1	&U1DBUFXADDR +#define SPI_CSR_1	U1CSR +#define SPI_BAUD_1	U1BAUD +#define SPI_GCR_1	U1GCR +#define SPI_CFG_MASK_1	PERCFG_U1CFG_ALT_MASK +#define SPI_DMA_TX_1	DMA_CFG0_TRIGGER_UTX1 +#define SPI_DMA_RX_1	DMA_CFG0_TRIGGER_URX1  #if SPI_1_ALT_1 -#define SPI_CFG		PERCFG_U1CFG_ALT_1 -#define SPI_SEL		P0SEL -#define SPI_BITS	(1 << 4) | (1 << 5) | (1 << 3) -#define SPI_CSS_BIT	(1 << 2) +#define SPI_CFG_1	PERCFG_U1CFG_ALT_1 +#define SPI_SEL_1	P0SEL +#define SPI_BITS_1	(1 << 4) | (1 << 5) | (1 << 3) +#define SPI_CSS_BIT_1	(1 << 2)  #endif  #if SPI_1_ALT_2 -#define SPI_CFG		PERCFG_U1CFG_ALT_2 -#define SPI_SEL		P1SEL -#define SPI_PRI		P2SEL_PRI3P1_USART1 -#define SPI_BITS	(1 << 6) | (1 << 7) | (1 << 5) -#define SPI_CSS_BIT	(1 << 4) +#define SPI_CFG_1	PERCFG_U1CFG_ALT_2 +#define SPI_SEL_1	P1SEL +#define SPI_PRI_1	P2SEL_PRI3P1_USART1 +#define SPI_BITS_1	(1 << 6) | (1 << 7) | (1 << 5) +#define SPI_CSS_BIT_1	(1 << 4)  #endif  #endif +#if MULTI_SPI + +#define SPI_BUF(bus)		((bus) ? SPI_BUF_1 : SPI_BUF_0) +#define SPI_CSR(bus)		((bus) ? SPI_CSR_1 : SPI_CSR_0) +#define SPI_BAUD(bus)		((bus) ? SPI_BAUD_1 : SPI_BAUD_0) +#define SPI_GCR(bus)		((bus) ? SPI_GCR_1 : SPI_GCR_0) +#define SPI_CFG_MASK(bus)	((bus) ? SPI_CFG_MASK_1 : SPI_CFG_MASK_0) +#define SPI_DMA_TX(bus)		((bus) ? SPI_DMA_TX_1 : SPI_DMA_TX_0) +#define SPI_DMA_RX(bus)		((bus) ? SPI_DMA_RX_1 : SPI_DMA_RX_0) +#define SPI_CFG(bus)		((bus) ? SPI_CFG_1 : SPI_CFG_0) +#define SPI_SEL(bus)		((bus) ? SPI_SEL_1 : SPI_SEL_0) +#define SPI_BITS(bus)		((bus) ? SPI_BITS_1 : SPI_BITS_0) +#define SPI_CSS_BIT(bus)	((bus) ? SPI_CSS_BIT_1 : SPI_CSS_BIT_0) + +#else + +#if HAS_SPI_0 +#define SPI_BUF(bus)		SPI_BUF_0 +#define SPI_CSR(bus)		SPI_CSR_0 +#define SPI_BAUD(bus)		SPI_BAUD_0 +#define SPI_GCR(bus)		SPI_GCR_0 +#define SPI_CFG_MASK(bus)	SPI_CFG_MASK_0 +#define SPI_DMA_TX(bus)		SPI_DMA_TX_0 +#define SPI_DMA_RX(bus)		SPI_DMA_RX_0 +#define SPI_CFG(bus)		SPI_CFG_0 +#define SPI_SEL(bus)		SPI_SEL_0 +#define SPI_BITS(bus)		SPI_BITS_0 +#define SPI_CSS_BIT(bus)	SPI_CSS_BIT_0 +#endif +#if HAS_SPI_1 +#define SPI_BUF(bus)		SPI_BUF_1 +#define SPI_CSR(bus)		SPI_CSR_1 +#define SPI_BAUD(bus)		SPI_BAUD_1 +#define SPI_GCR(bus)		SPI_GCR_1 +#define SPI_CFG_MASK(bus)	SPI_CFG_MASK_1 +#define SPI_DMA_TX(bus)		SPI_DMA_TX_1 +#define SPI_DMA_RX(bus)		SPI_DMA_RX_1 +#define SPI_CFG(bus)		SPI_CFG_1 +#define SPI_SEL(bus)		SPI_SEL_1 +#define SPI_BITS(bus)		SPI_BITS_1 +#define SPI_CSS_BIT(bus)	SPI_CSS_BIT_1 +#endif + +#endif /* MULTI_SPI */ +  #if AO_SPI_SLAVE -#define CSS		SPI_CSS_BIT +#define CSS(bus)		SPI_CSS_BIT(bus)  #define UxCSR_DIRECTION	UxCSR_SLAVE  #else -#define CSS		0 +#define CSS(bus)		0  #define UxCSR_DIRECTION	UxCSR_MASTER  #endif @@ -124,15 +165,16 @@   * operation, from CS low to CS high. This means that any SPI   * user must protect the SPI bus with this mutex   */ -__xdata uint8_t	ao_spi_mutex; -__xdata uint8_t ao_spi_dma_in_done; -__xdata uint8_t ao_spi_dma_out_done; +__xdata uint8_t	ao_spi_mutex[N_SPI]; +__xdata uint8_t ao_spi_dma_in_done[N_SPI]; +__xdata uint8_t ao_spi_dma_out_done[N_SPI]; -uint8_t	ao_spi_dma_out_id; -uint8_t ao_spi_dma_in_id; +uint8_t	ao_spi_dma_out_id[N_SPI]; +uint8_t ao_spi_dma_in_id[N_SPI];  static __xdata uint8_t ao_spi_const; +  /* Send bytes over SPI.   *   * This sets up two DMA engines, one writing the data and another reading @@ -140,45 +182,52 @@ static __xdata uint8_t ao_spi_const;   * is complete, as the transmit register is double buffered and hence signals   * completion one byte before the transfer is actually complete   */ +#if MULTI_SPI +void +ao_spi_send(void __xdata *block, uint16_t len, uint8_t bus) __reentrant +#else  void  ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant +#define bus	0 +#endif  { -	ao_dma_set_transfer(ao_spi_dma_in_id, -			    &SPI_BUF, +	ao_dma_set_transfer(ao_spi_dma_in_id[bus], +			    SPI_BUF(bus),  			    &ao_spi_const,  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    SPI_DMA_RX, +			    SPI_DMA_RX(bus),  			    DMA_CFG1_SRCINC_0 |  			    DMA_CFG1_DESTINC_0 |  			    DMA_CFG1_PRIORITY_NORMAL); -	ao_dma_set_transfer(ao_spi_dma_out_id, +	ao_dma_set_transfer(ao_spi_dma_out_id[bus],  			    block, -			    &SPI_BUF, +			    SPI_BUF(bus),  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    SPI_DMA_TX, +			    SPI_DMA_TX(bus),  			    DMA_CFG1_SRCINC_1 |  			    DMA_CFG1_DESTINC_0 |  			    DMA_CFG1_PRIORITY_NORMAL); -	ao_dma_start(ao_spi_dma_in_id); -	ao_dma_start(ao_spi_dma_out_id); -	ao_dma_trigger(ao_spi_dma_out_id); +	ao_dma_start(ao_spi_dma_in_id[bus]); +	ao_dma_start(ao_spi_dma_out_id[bus]); +	ao_dma_trigger(ao_spi_dma_out_id[bus]);  #if !AO_SPI_SLAVE -	__critical while (!ao_spi_dma_in_done) -		ao_sleep(&ao_spi_dma_in_done); +	__critical while (!ao_spi_dma_in_done[bus]) +		ao_sleep(&ao_spi_dma_in_done[bus]);  #endif +#undef bus  }  #if AO_SPI_SLAVE  void  ao_spi_send_wait(void)  { -	__critical while (!ao_spi_dma_in_done) -		ao_sleep(&ao_spi_dma_in_done); +	__critical while (!ao_spi_dma_in_done[0]) +		ao_sleep(&ao_spi_dma_in_done[0]);  }  #endif @@ -188,16 +237,22 @@ ao_spi_send_wait(void)   * writing constant values to the SPI transmitter as that is what   * clocks the data coming in.   */ +#if MULTI_SPI +void +ao_spi_recv(void __xdata *block, uint16_t len, uint8_t bus) __reentrant +#else  void  ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant +#define bus 0 +#endif  { -	ao_dma_set_transfer(ao_spi_dma_in_id, -			    &SPI_BUF, +	ao_dma_set_transfer(ao_spi_dma_in_id[bus], +			    SPI_BUF(bus),  			    block,  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    SPI_DMA_RX, +			    SPI_DMA_RX(bus),  			    DMA_CFG1_SRCINC_0 |  			    DMA_CFG1_DESTINC_1 |  			    DMA_CFG1_PRIORITY_NORMAL); @@ -205,24 +260,24 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant  	ao_spi_const = SPI_CONST;  #if !AO_SPI_SLAVE -	ao_dma_set_transfer(ao_spi_dma_out_id, +	ao_dma_set_transfer(ao_spi_dma_out_id[bus],  			    &ao_spi_const, -			    &SPI_BUF, +			    SPI_BUF(bus),  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    SPI_DMA_TX, +			    SPI_DMA_TX(bus),  			    DMA_CFG1_SRCINC_0 |  			    DMA_CFG1_DESTINC_0 |  			    DMA_CFG1_PRIORITY_NORMAL);  #endif -	ao_dma_start(ao_spi_dma_in_id); +	ao_dma_start(ao_spi_dma_in_id[bus]);  #if !AO_SPI_SLAVE -	ao_dma_start(ao_spi_dma_out_id); -	ao_dma_trigger(ao_spi_dma_out_id); -	__critical while (!ao_spi_dma_in_done) -		ao_sleep(&ao_spi_dma_in_done); +	ao_dma_start(ao_spi_dma_out_id[bus]); +	ao_dma_trigger(ao_spi_dma_out_id[bus]); +	__critical while (!ao_spi_dma_in_done[bus]) +		ao_sleep(&ao_spi_dma_in_done[bus]);  #endif  } @@ -230,17 +285,43 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant  void  ao_spi_recv_wait(void)  { -	__critical while (!ao_spi_dma_in_done) -		ao_sleep(&ao_spi_dma_in_done); +	__critical while (!ao_spi_dma_in_done[0]) +		ao_sleep(&ao_spi_dma_in_done[0]);  }  #endif +/* Set up the USART. + * + * SPI master/slave mode + */ +/* Set the baud rate and signal parameters + * + * The cc1111 is limited to a 24/8 MHz SPI clock. + * Every peripheral I've ever seen goes faster than that, + * so set the clock to 3MHz (BAUD_E 17, BAUD_M 0) + */ +#define SPI_INIT(bus,o)	do {						\ +		/* Set up the USART pin assignment */			\ +		PERCFG = (PERCFG & ~SPI_CFG_MASK(bus)) | SPI_CFG(bus);	\ +									\ +		/* Make the SPI pins be controlled by the USART peripheral */ \ +		SPI_SEL(bus) |= SPI_BITS(bus) | CSS(bus);		\ +		SPI_CSR(bus) = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION); \ +		SPI_BAUD(bus) = 0;					\ +		SPI_GCR(bus) = (UxGCR_CPOL_NEGATIVE |			\ +				UxGCR_CPHA_FIRST_EDGE |			\ +				UxGCR_ORDER_MSB |			\ +				(17 << UxGCR_BAUD_E_SHIFT));		\ +		/* Set up OUT DMA */					\ +		ao_spi_dma_out_id[o] = ao_dma_alloc(&ao_spi_dma_out_done[o]); \ +									\ +		/* Set up IN DMA */					\ +		ao_spi_dma_in_id[o] = ao_dma_alloc(&ao_spi_dma_in_done[o]);	\ +	} while (0) +  void  ao_spi_init(void)  { -	/* Set up the USART pin assignment */ -	PERCFG = (PERCFG & ~SPI_CFG_MASK) | SPI_CFG; -  	/* Ensure that SPI USART takes precidence over the other USART  	 * for pins that they share  	 */ @@ -248,30 +329,10 @@ ao_spi_init(void)  	P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | SPI_PRI;  #endif -	/* Make the SPI pins be controlled by the USART peripheral */ -	SPI_SEL |= SPI_BITS | CSS; - -	/* Set up OUT DMA */ -	ao_spi_dma_out_id = ao_dma_alloc(&ao_spi_dma_out_done); - -	/* Set up IN DMA */ -	ao_spi_dma_in_id = ao_dma_alloc(&ao_spi_dma_in_done); - -	/* Set up the USART. -	 * -	 * SPI master/slave mode -	 */ -	SPI_CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION); - -	/* Set the baud rate and signal parameters -	 * -	 * The cc1111 is limited to a 24/8 MHz SPI clock. -	 * Every peripheral I've ever seen goes faster than that, -	 * so set the clock to 3MHz (BAUD_E 17, BAUD_M 0) -	 */ -	SPI_BAUD = 0; -	SPI_GCR = (UxGCR_CPOL_NEGATIVE | -		   UxGCR_CPHA_FIRST_EDGE | -		   UxGCR_ORDER_MSB | -		   (17 << UxGCR_BAUD_E_SHIFT)); +#if HAS_SPI_0 +	SPI_INIT(0, 0); +#endif +#if HAS_SPI_1 +	SPI_INIT(1, MULTI_SPI); +#endif  } | 
