watch library: implement SPI
This commit is contained in:
		
							parent
							
								
									1b1bba2de0
								
							
						
					
					
						commit
						a11275d84c
					
				| @ -3,40 +3,10 @@ | ||||
| #include <peripheral_clk_config.h> | ||||
| #include "watch.h" | ||||
| 
 | ||||
| // NOTE: as of this writing (10/25/21) there is no SPI controller functionality in the watch library.
 | ||||
| // this is a very basic app to confirm that SPI is working, tested with board OSO-MISC-21-001 and a GD25Q16C Flash chip.
 | ||||
| // The updated SPI Flash sensor board design is OSO-MISC-21-017 (it's easier to build, 0603 passives instead of 0402's).
 | ||||
| 
 | ||||
| struct io_descriptor *io; | ||||
| struct spi_m_sync_descriptor SPI_0; | ||||
| // this is a very basic app to confirm that SPI is working, tested with board OSO-MISC-21-017 and a GD25Q16C Flash chip.
 | ||||
| 
 | ||||
| void app_init(void) { | ||||
|     // SPI_0_CLOCK_init
 | ||||
|     hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM3_GCLK_ID_CORE, CONF_GCLK_SERCOM3_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); | ||||
|     hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM3_GCLK_ID_SLOW, CONF_GCLK_SERCOM3_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); | ||||
|     hri_mclk_set_APBCMASK_SERCOM3_bit(MCLK); | ||||
| 
 | ||||
|     spi_m_sync_init(&SPI_0, SERCOM3); | ||||
| 
 | ||||
|     // SPI_0_PORT_init
 | ||||
|     gpio_set_pin_level(A3, true); | ||||
|     gpio_set_pin_direction(A3, GPIO_DIRECTION_OUT); | ||||
|     gpio_set_pin_function(A3, GPIO_PIN_FUNCTION_OFF); | ||||
| 
 | ||||
|     gpio_set_pin_level(A2, false); | ||||
|     gpio_set_pin_direction(A2, GPIO_DIRECTION_OUT); | ||||
|     gpio_set_pin_function(A2, PINMUX_PB02C_SERCOM3_PAD0); | ||||
| 
 | ||||
|     gpio_set_pin_direction(A4, GPIO_DIRECTION_IN); | ||||
|     gpio_set_pin_pull_mode(A4, GPIO_PULL_OFF); | ||||
|     gpio_set_pin_function(A4, PINMUX_PB00C_SERCOM3_PAD2); | ||||
| 
 | ||||
|     gpio_set_pin_level(A1, false); | ||||
|     gpio_set_pin_direction(A1, GPIO_DIRECTION_OUT); | ||||
|     gpio_set_pin_function(A1, PINMUX_PB01C_SERCOM3_PAD3); | ||||
| 
 | ||||
|     spi_m_sync_get_io_descriptor(&SPI_0, &io); | ||||
|     spi_m_sync_enable(&SPI_0); | ||||
|     watch_enable_spi(); | ||||
| } | ||||
| 
 | ||||
| void app_wake_from_backup(void) { | ||||
| @ -51,20 +21,23 @@ void app_prepare_for_standby(void) { | ||||
| void app_wake_from_standby(void) { | ||||
| } | ||||
| 
 | ||||
| static uint8_t get_id_command[4] = {0x9F}; | ||||
| 
 | ||||
| bool app_loop(void) { | ||||
|     watch_set_pin_level(A3, false); | ||||
|     io_write(io, get_id_command, 1); | ||||
|     uint8_t get_id_command[1] = {0x9F}; | ||||
|     uint8_t buf[3] = {0}; | ||||
| 
 | ||||
|     watch_set_pin_level(A3, false); | ||||
| 
 | ||||
|     // should print 0, 0, 0
 | ||||
|     watch_spi_send(get_id_command, 1); | ||||
|     printf("blank: %x, %x, %x\n", buf[0], buf[1], buf[2]); | ||||
|     io_read(io, buf, 3); | ||||
|     watch_set_pin_level(A3, true); | ||||
| 
 | ||||
|     // should print c8, 40, 15
 | ||||
|     watch_spi_receive(buf, 3); | ||||
|     printf("ident: %x, %x, %x\n", buf[0], buf[1], buf[2]); | ||||
| 
 | ||||
|     watch_set_pin_level(A3, true); | ||||
| 
 | ||||
|     delay_ms(100); | ||||
| 
 | ||||
|     return false; | ||||
|  | ||||
							
								
								
									
										2
									
								
								make.mk
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								make.mk
									
									
									
									
									
								
							| @ -85,6 +85,7 @@ SRCS += \ | ||||
|   $(TOP)/watch-library/hardware/watch/watch_adc.c \
 | ||||
|   $(TOP)/watch-library/hardware/watch/watch_gpio.c \
 | ||||
|   $(TOP)/watch-library/hardware/watch/watch_i2c.c \
 | ||||
|   $(TOP)/watch-library/hardware/watch/watch_spi.c \
 | ||||
|   $(TOP)/watch-library/hardware/watch/watch_uart.c \
 | ||||
|   $(TOP)/watch-library/hardware/watch/watch_deepsleep.c \
 | ||||
|   $(TOP)/watch-library/hardware/watch/watch_private.c \
 | ||||
| @ -152,6 +153,7 @@ SRCS += \ | ||||
|   $(TOP)/watch-library/simulator/watch/watch_adc.c \
 | ||||
|   $(TOP)/watch-library/simulator/watch/watch_gpio.c \
 | ||||
|   $(TOP)/watch-library/simulator/watch/watch_i2c.c \
 | ||||
|   $(TOP)/watch-library/simulator/watch/watch_spi.c \
 | ||||
|   $(TOP)/watch-library/simulator/watch/watch_uart.c \
 | ||||
|   $(TOP)/watch-library/simulator/watch/watch_deepsleep.c \
 | ||||
|   $(TOP)/watch-library/simulator/watch/watch_private.c \
 | ||||
|  | ||||
| @ -15,6 +15,8 @@ struct slcd_sync_descriptor SEGMENT_LCD_0; | ||||
| 
 | ||||
| struct i2c_m_sync_desc I2C_0; | ||||
| 
 | ||||
| struct spi_m_sync_descriptor SPI_0; | ||||
| 
 | ||||
| void I2C_0_PORT_init(void) { | ||||
| 
 | ||||
| 	gpio_set_pin_pull_mode(SDA, | ||||
| @ -50,6 +52,68 @@ void I2C_0_init(void) { | ||||
| 	I2C_0_PORT_init(); | ||||
| } | ||||
| 
 | ||||
| void SPI_0_PORT_init(void) { | ||||
| 
 | ||||
| 	gpio_set_pin_level(A2, | ||||
| 	                   // <y> Initial level
 | ||||
| 	                   // <id> pad_initial_level
 | ||||
| 	                   // <false"> Low
 | ||||
| 	                   // <true"> High
 | ||||
| 	                   false); | ||||
| 
 | ||||
| 	// Set pin direction to output
 | ||||
| 	gpio_set_pin_direction(A2, GPIO_DIRECTION_OUT); | ||||
| 
 | ||||
| 	gpio_set_pin_function(A2, PINMUX_PB02C_SERCOM3_PAD0); | ||||
| 
 | ||||
| 	// Set pin direction to input
 | ||||
| 	gpio_set_pin_direction(A4, GPIO_DIRECTION_IN); | ||||
| 
 | ||||
| 	gpio_set_pin_pull_mode(A4, | ||||
| 	                       // <y> Pull configuration
 | ||||
| 	                       // <id> pad_pull_config
 | ||||
| 	                       // <GPIO_PULL_OFF"> Off
 | ||||
| 	                       // <GPIO_PULL_UP"> Pull-up
 | ||||
| 	                       // <GPIO_PULL_DOWN"> Pull-down
 | ||||
| 	                       GPIO_PULL_OFF); | ||||
| 
 | ||||
| 	gpio_set_pin_function(A4, PINMUX_PB00C_SERCOM3_PAD2); | ||||
| 
 | ||||
| 	gpio_set_pin_level(A1, | ||||
| 	                   // <y> Initial level
 | ||||
| 	                   // <id> pad_initial_level
 | ||||
| 	                   // <false"> Low
 | ||||
| 	                   // <true"> High
 | ||||
| 	                   false); | ||||
| 
 | ||||
| 	// Set pin direction to output
 | ||||
| 	gpio_set_pin_direction(A1, GPIO_DIRECTION_OUT); | ||||
| 
 | ||||
| 	gpio_set_pin_function(A1, PINMUX_PB01C_SERCOM3_PAD3); | ||||
| 
 | ||||
| 	gpio_set_pin_level(A3, | ||||
| 	                   // <y> Initial level
 | ||||
| 	                   // <id> pad_initial_level
 | ||||
| 	                   // <false"> Low
 | ||||
| 	                   // <true"> High
 | ||||
| 	                   true); | ||||
| 
 | ||||
| 	// Set pin direction to output
 | ||||
| 	gpio_set_pin_direction(A3, GPIO_DIRECTION_OUT); | ||||
| } | ||||
| 
 | ||||
| void SPI_0_CLOCK_init(void) { | ||||
| 	hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM3_GCLK_ID_CORE, CONF_GCLK_SERCOM3_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); | ||||
| 	hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM3_GCLK_ID_SLOW, CONF_GCLK_SERCOM3_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); | ||||
| 	hri_mclk_set_APBCMASK_SERCOM3_bit(MCLK); | ||||
| } | ||||
| 
 | ||||
| void SPI_0_init(void) { | ||||
| 	SPI_0_CLOCK_init(); | ||||
| 	spi_m_sync_init(&SPI_0, SERCOM3); | ||||
| 	SPI_0_PORT_init(); | ||||
| } | ||||
| 
 | ||||
| void delay_driver_init(void) { | ||||
| 	delay_init(SysTick); | ||||
| } | ||||
|  | ||||
| @ -43,12 +43,18 @@ extern struct i2c_m_sync_desc I2C_0; | ||||
| 
 | ||||
| extern struct usart_sync_descriptor USART_0; | ||||
| 
 | ||||
| extern struct spi_m_sync_descriptor SPI_0; | ||||
| 
 | ||||
| extern struct slcd_sync_descriptor SEGMENT_LCD_0; | ||||
| 
 | ||||
| void I2C_0_CLOCK_init(void); | ||||
| void I2C_0_init(void); | ||||
| void I2C_0_PORT_init(void); | ||||
| 
 | ||||
| void SPI_0_PORT_init(void); | ||||
| void SPI_0_CLOCK_init(void); | ||||
| void SPI_0_init(void); | ||||
| 
 | ||||
| void delay_driver_init(void); | ||||
| 
 | ||||
| void EXTERNAL_IRQ_0_init(void); | ||||
|  | ||||
							
								
								
									
										46
									
								
								watch-library/hardware/watch/watch_spi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								watch-library/hardware/watch/watch_spi.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| /*
 | ||||
|  * MIT License | ||||
|  * | ||||
|  * Copyright (c) 2022 Joey Castillo | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include "watch_spi.h" | ||||
| 
 | ||||
| struct io_descriptor *spi_io; | ||||
| 
 | ||||
| void watch_enable_spi(void) { | ||||
|     SPI_0_init(); | ||||
|     spi_m_sync_get_io_descriptor(&SPI_0, &spi_io); | ||||
|     spi_m_sync_enable(&SPI_0); | ||||
| } | ||||
| 
 | ||||
| void watch_disable_spi(void) { | ||||
|     spi_m_sync_disable(&SPI_0); | ||||
|     spi_io = NULL; | ||||
| } | ||||
| 
 | ||||
| void watch_spi_send(uint8_t *buf, uint16_t length) { | ||||
| 	io_write(spi_io, buf, length); | ||||
| } | ||||
| 
 | ||||
| void watch_spi_receive(uint8_t *buf, uint16_t length) { | ||||
| 	io_read(spi_io, buf, length); | ||||
| } | ||||
| @ -60,6 +60,7 @@ | ||||
| #include "watch_adc.h" | ||||
| #include "watch_gpio.h" | ||||
| #include "watch_i2c.h" | ||||
| #include "watch_spi.h" | ||||
| #include "watch_uart.h" | ||||
| #include "watch_deepsleep.h" | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										59
									
								
								watch-library/shared/watch/watch_spi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								watch-library/shared/watch/watch_spi.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| /*
 | ||||
|  * MIT License | ||||
|  * | ||||
|  * Copyright (c) 2022 Joey Castillo | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _WATCH_SPI_H_INCLUDED | ||||
| #define _WATCH_SPI_H_INCLUDED | ||||
| ////< @file watch_spi.h
 | ||||
| 
 | ||||
| #include "watch.h" | ||||
| 
 | ||||
| /** @addtogroup spi SPI Controller Driver
 | ||||
|   * @brief This section covers functions related to the SAM L22's built-in SPI driver, including | ||||
|   *        configuring the SPI bus and writing to / reading from devices. | ||||
|   */ | ||||
| /// @{
 | ||||
| /** @brief Enables the SPI peripheral. Call this before attempting to interface with SPI devices.
 | ||||
|   */ | ||||
| void watch_enable_spi(void); | ||||
| 
 | ||||
| /** @brief Disables the SPI peripheral.
 | ||||
|   */ | ||||
| void watch_disable_spi(void); | ||||
| 
 | ||||
| /** @brief Sends a series of values to a device on the SPI bus.
 | ||||
|   * @param buf A series of unsigned bytes; the data you wish to transmit. | ||||
|   * @param length The number of bytes in buf that you wish to send. | ||||
|   * @note This function does not manage the chip select pin (usually A3). | ||||
|   */ | ||||
| void watch_spi_send(uint8_t *buf, uint16_t length); | ||||
| 
 | ||||
| /** @brief Receives a series of values from a device on the SPI bus.
 | ||||
|   * @param buf Storage for the incoming bytes; on return, it will contain the received data. | ||||
|   * @param length The number of bytes that you wish to receive. | ||||
|   * @note This function does not manage the chip select pin (usually A3). | ||||
|   */ | ||||
| void watch_spi_receive(uint8_t *buf, uint16_t length); | ||||
| 
 | ||||
| /// @}
 | ||||
| #endif | ||||
							
								
								
									
										33
									
								
								watch-library/simulator/watch/watch_spi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								watch-library/simulator/watch/watch_spi.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| /*
 | ||||
|  * MIT License | ||||
|  * | ||||
|  * Copyright (c) 2022 Joey Castillo | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include "watch_spi.h" | ||||
| 
 | ||||
| void watch_enable_spi(void) {} | ||||
| 
 | ||||
| void watch_disable_spi(void) {} | ||||
| 
 | ||||
| void watch_spi_send(uint8_t *buf, uint16_t length) {} | ||||
| 
 | ||||
| void watch_spi_receive(uint8_t *buf, uint16_t length) {} | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user