diff options
Diffstat (limited to 'src/cc1111/ao_spi.c')
| -rw-r--r-- | src/cc1111/ao_spi.c | 188 | 
1 files changed, 128 insertions, 60 deletions
| diff --git a/src/cc1111/ao_spi.c b/src/cc1111/ao_spi.c index 52087fb4..e7480fd7 100644 --- a/src/cc1111/ao_spi.c +++ b/src/cc1111/ao_spi.c @@ -17,6 +17,109 @@  #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 +#endif + +/* + * USART0 SPI config alt 1 + *  + *	MO	P0_3 + *	MI	P0_2 + *	CLK	P0_5 + *	SS	P0_4 + * + * USART0 SPI config alt 2 + * + * 	MO	P1_5 + * 	MI	P1_4 + * 	CLK	P1_3 + *	CSS	P1_2 + * + * USART1 SPI config alt 1 + * + *	MO	P0_4 + *	MI	P0_5 + *	CLK	P0_3 + *	SS	P0_2 + * + * USART1 SPI config alt 2 + * + *	MO	P1_6 + *	MI	P1_7 + *	CLK	P1_5 + *	SS	P1_4 + * + * + * Chip select is the responsibility of the caller in master mode + */ + +#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 + +#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) +#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) +#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 + +#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) +#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) +#endif + +#endif + +#if AO_SPI_SLAVE +#define CSS		SPI_CSS_BIT +#define UxCSR_DIRECTION	UxCSR_SLAVE +#else +#define CSS		0 +#define UxCSR_DIRECTION	UxCSR_MASTER +#endif +  /* Shared mutex to protect SPI bus, must cover the entire   * operation, from CS low to CS high. This means that any SPI   * user must protect the SPI bus with this mutex @@ -42,23 +145,23 @@ ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant  {  #if !AO_SPI_SLAVE  	ao_dma_set_transfer(ao_spi_dma_in_id, -			    &U0DBUFXADDR, +			    &SPI_BUF,  			    &ao_spi_const,  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    DMA_CFG0_TRIGGER_URX0, +			    SPI_DMA_RX,  			    DMA_CFG1_SRCINC_0 |  			    DMA_CFG1_DESTINC_0 |  			    DMA_CFG1_PRIORITY_NORMAL);  #endif  	ao_dma_set_transfer(ao_spi_dma_out_id,  			    block, -			    &U0DBUFXADDR, +			    &SPI_BUF,  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    DMA_CFG0_TRIGGER_UTX0, +			    SPI_DMA_TX,  			    DMA_CFG1_SRCINC_1 |  			    DMA_CFG1_DESTINC_0 |  			    DMA_CFG1_PRIORITY_NORMAL); @@ -77,6 +180,8 @@ ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant  #endif  } + +  /* Receive bytes over SPI.   *   * This sets up tow DMA engines, one reading the data and another @@ -87,25 +192,25 @@ void  ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant  {  	ao_dma_set_transfer(ao_spi_dma_in_id, -			    &U0DBUFXADDR, +			    &SPI_BUF,  			    block,  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    DMA_CFG0_TRIGGER_URX0, +			    SPI_DMA_RX,  			    DMA_CFG1_SRCINC_0 |  			    DMA_CFG1_DESTINC_1 |  			    DMA_CFG1_PRIORITY_NORMAL); -	ao_spi_const = 0xff; +	ao_spi_const = SPI_CONST;  	ao_dma_set_transfer(ao_spi_dma_out_id,  			    &ao_spi_const, -			    &U0DBUFXADDR, +			    &SPI_BUF,  			    len,  			    DMA_CFG0_WORDSIZE_8 |  			    DMA_CFG0_TMODE_SINGLE | -			    DMA_CFG0_TRIGGER_UTX0, +			    SPI_DMA_TX,  			    DMA_CFG1_SRCINC_0 |  			    DMA_CFG1_DESTINC_0 |  			    DMA_CFG1_PRIORITY_NORMAL); @@ -117,59 +222,22 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant  		ao_sleep(&ao_spi_dma_in_done);  } -/* - * USART0 SPI config alt 2	 (using this one) - * - * 	MO	P1_5 - * 	MI	P1_4 - * 	CLK	P1_3 - *	CSS	P1_2 - * - * USART0 SPI config alt 1 - *  - *	MO	P0_3 - *	MI	P0_2 - *	CLK	P0_5 - *	SS	P0_4 - * - * USART1 SPI config alt 2 - * - *	MO	P1_6 - *	MI	P1_7 - *	CLK	P1_5 - *	SS	P1_4 - * - * USART1 SPI config alt 1 - * - *	MO	P0_4 - *	MI	P0_5 - *	CLK	P0_3 - *	SS	P0_2 - * - * Chip select is the responsibility of the caller in master mode - */ - -#if AO_SPI_SLAVE -#define CSS	(1 << 2) -#define UxCSR_DIRECTION	UxCSR_SLAVE -#else -#define CSS	0 -#define UxCSR_DIRECTION	UxCSR_MASTER -#endif  void  ao_spi_init(void)  {  	/* Set up the USART pin assignment */ -	PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_2; +	PERCFG = (PERCFG & ~SPI_CFG_MASK) | SPI_CFG; -	/* Ensure that USART0 takes precidence over USART1 for pins that -	 * they share +	/* Ensure that SPI USART takes precidence over the other USART +	 * for pins that they share  	 */ -	P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | P2SEL_PRI3P1_USART0; +#ifdef SPI_PRI +	P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | SPI_PRI; +#endif  	/* Make the SPI pins be controlled by the USART peripheral */ -	P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3) | CSS); +	SPI_SEL |= SPI_BITS | CSS;  	/* Set up OUT DMA */  	ao_spi_dma_out_id = ao_dma_alloc(&ao_spi_dma_out_done); @@ -179,9 +247,9 @@ ao_spi_init(void)  	/* Set up the USART.  	 * -	 * SPI master mode +	 * SPI master/slave mode  	 */ -	U0CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION); +	SPI_CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION);  	/* Set the baud rate and signal parameters  	 * @@ -189,9 +257,9 @@ ao_spi_init(void)  	 * Every peripheral I've ever seen goes faster than that,  	 * so set the clock to 3MHz (BAUD_E 17, BAUD_M 0)  	 */ -	U0BAUD = 0; -	U0GCR = (UxGCR_CPOL_NEGATIVE | -		 UxGCR_CPHA_FIRST_EDGE | -		 UxGCR_ORDER_MSB | -		 (17 << UxGCR_BAUD_E_SHIFT)); +	SPI_BAUD = 0; +	SPI_GCR = (UxGCR_CPOL_NEGATIVE | +		   UxGCR_CPHA_FIRST_EDGE | +		   UxGCR_ORDER_MSB | +		   (17 << UxGCR_BAUD_E_SHIFT));  } | 
