diff --git a/src/py/py_spi.c b/src/py/py_spi.c new file mode 100644 index 000000000..182c2d226 --- /dev/null +++ b/src/py/py_spi.c @@ -0,0 +1,48 @@ +#include +#include "spi.h" +#include "py_assert.h" +#include "py_spi.h" +#include "imlib.h" +#include "py_image.h" + +mp_obj_t py_spi_read() +{ + return mp_obj_new_int(spi_read()); +} + +mp_obj_t py_spi_write(mp_obj_t c) +{ + spi_write(mp_obj_get_int(c)); + return mp_const_true; +} + +mp_obj_t py_spi_write_image(mp_obj_t image_obj) +{ + struct image *image; + /* get image pointer */ + image = (struct image*) py_image_cobj(image_obj); + + uint16_t *pixels = (uint16_t*)image->data; + for (int j=0;jh;j++) { + for (int i=0;iw;i++) { + uint16_t c = pixels[j*image->w+i]; + spi_write(c); + spi_write(c>>8); + } + } + return mp_const_none; +} + +mp_obj_t py_spi_init() +{ + spi_init(); + + /* Create module */ + mp_obj_t m = mp_obj_new_module(qstr_from_str("spi")); + + /* Export functions */ + rt_store_attr(m, qstr_from_str("read"), rt_make_function_n(0, py_spi_read)); + rt_store_attr(m, qstr_from_str("write"), rt_make_function_n(1, py_spi_write)); + rt_store_attr(m, qstr_from_str("write_image"), rt_make_function_n(1, py_spi_write_image)); + return m; +} diff --git a/src/py/py_spi.h b/src/py/py_spi.h new file mode 100644 index 000000000..13b75e522 --- /dev/null +++ b/src/py/py_spi.h @@ -0,0 +1,5 @@ +#ifndef __PY_SPI_H__ +#define __PY_SPI_H__ +mp_obj_t py_spi_init(); +#endif /* __PY_SPI_H__ */ + diff --git a/src/spi.c b/src/spi.c new file mode 100644 index 000000000..cd9412575 --- /dev/null +++ b/src/spi.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include "spi.h" + +#define GPIO_SPI_AF GPIO_AF_SPI3 + +#define GPIO_PIN_CS GPIO_Pin_15 +#define GPIO_PIN_SCLK GPIO_Pin_10 +#define GPIO_PIN_MISO GPIO_Pin_11 +#define GPIO_PIN_MOSI GPIO_Pin_12 + +#define GPIO_SOURCE_SCLK GPIO_PinSource10 +#define GPIO_SOURCE_MISO GPIO_PinSource11 +#define GPIO_SOURCE_MOSI GPIO_PinSource12 + +#define GPIO_PORT_CS GPIOA +#define GPIO_PORT_SCLK GPIOC +#define GPIO_PORT_MISO GPIOC +#define GPIO_PORT_MOSI GPIOC + +#define GPIO_CLK_CS RCC_AHB1Periph_GPIOA +#define GPIO_CLK_SCLK RCC_AHB1Periph_GPIOC +#define GPIO_CLK_MISO RCC_AHB1Periph_GPIOC +#define GPIO_CLK_MOSI RCC_AHB1Periph_GPIOC + +#define SPIx SPI3 +#define SPIx_CLK RCC_APB1Periph_SPI3 +#define SPIx_CLK_CMD RCC_APB1PeriphClockCmd +#define GPIO_CLK_CMD RCC_AHB1PeriphClockCmd + +void spi_init() +{ + SPI_InitTypeDef SPI_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable SPI clock */ + SPIx_CLK_CMD(SPIx_CLK, ENABLE); + + /* Enable GPIO clocks */ + GPIO_CLK_CMD(GPIO_CLK_CS | GPIO_CLK_SCLK | GPIO_CLK_MISO | GPIO_CLK_MOSI, ENABLE); + + /* Connect SPI pins to AF */ + GPIO_PinAFConfig(GPIO_PORT_SCLK, GPIO_SOURCE_SCLK, GPIO_SPI_AF); + GPIO_PinAFConfig(GPIO_PORT_MISO, GPIO_SOURCE_MISO, GPIO_SPI_AF); + GPIO_PinAFConfig(GPIO_PORT_MOSI, GPIO_SOURCE_MOSI, GPIO_SPI_AF); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + + /* SPI MISO pin configuration */ + GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MISO; + GPIO_Init(GPIO_PORT_MISO, &GPIO_InitStructure); + + /* SPI MOSI pin configuration */ + GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MOSI; + GPIO_Init(GPIO_PORT_MOSI, &GPIO_InitStructure); + + /* SPI SCK pin configuration */ + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_InitStructure.GPIO_Pin = GPIO_PIN_SCLK; + GPIO_Init(GPIO_PORT_SCLK, &GPIO_InitStructure); + + /* SPI configuration */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + + SPI_Init(SPIx, &SPI_InitStructure); + SPI_CalculateCRC(SPIx, DISABLE); + SPI_Cmd(SPIx, ENABLE); + + /* drain SPI */ + while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET); + + /* dummy read */ + SPI_I2S_ReceiveData(SPIx); +} + +uint8_t spi_read() +{ + /* Send byte through the SPI */ + SPI_I2S_SendData(SPIx, 0xFF); + + /* Wait to receive a byte */ + while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET); + + /* Read byte from the SPI */ + return SPI_I2S_ReceiveData(SPIx); +} + +uint8_t spi_write(uint8_t b) +{ + while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET); + + /* Send byte through the SPI */ + SPI_I2S_SendData(SPIx, b); + + /* Wait to receive a byte */ + while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET); + + /* Read byte from the SPI */ + return SPI_I2S_ReceiveData(SPIx); +} diff --git a/src/spi.h b/src/spi.h new file mode 100644 index 000000000..9ebb38055 --- /dev/null +++ b/src/spi.h @@ -0,0 +1,7 @@ +#ifndef __SPI_H__ +#define __SPI_H__ +#include +void spi_init(); +uint8_t spi_read(); +uint8_t spi_write(uint8_t b); +#endif /* __SPI_H__ */