#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/usart.h>
#include <stdio.h>
#include <errno.h>
void gpio_setup(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO7);
}
void usart_setup()
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN
| RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
usart_set_baudrate(USART1, 57600);
usart_set_databits(USART1, 8);
usart_set_stopbits(USART1, USART_STOPBITS_1);
usart_set_mode(USART1, USART_MODE_TX);
usart_set_parity(USART1, USART_PARITY_NONE);
usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
usart_enable(USART1);
}
void spi_setup()
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SPI1EN);
rcc_peripheral_enable_clock(&RCC_APB2ENR,
RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO5 | GPIO7);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO4);
spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_64, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE,
SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
spi_enable_software_slave_management(SPI1);
spi_set_nss_high(SPI1);
spi_enable(SPI1);
}
int _write(int file, char *ptr, int len)
{
int i;
if (file == 1) {
for (i = 0; i < len; i++) {
usart_send_blocking(USART1, ptr[i]);
}
return i;
}
errno = EIO;
return -1;
}
void ncs_set()
{
gpio_clear(GPIOA, GPIO4);
}
void ncs_clear()
{
gpio_set(GPIOA, GPIO4);
}
uint8_t adns3080_read(uint8_t addr)
{
int i;
ncs_set();
for (i = 0; i < 200; i++)
__asm__("nop");
spi_xfer(SPI1, addr);
for (i = 0; i < 200; i++)
__asm__("nop");
uint8_t val = spi_xfer(SPI1, 0x00);
for (i = 0; i < 200; i++)
__asm__("nop");
ncs_clear();
return val;
}
void adns3080_write(uint8_t addr, uint8_t val)
{
int i;
ncs_set();
for (i = 0; i < 200; i++)
__asm__("nop");
spi_xfer(SPI1, 0x80 | addr);
for (i = 0; i < 200; i++)
__asm__("nop");
spi_xfer(SPI1, val);
for (i = 0; i < 200; i++)
__asm__("nop");
ncs_clear();
}
int main(void)
{
int i;
rcc_clock_setup_in_hse_8mhz_out_72mhz();
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
gpio_setup();
spi_setup();
usart_setup();
ncs_clear();
for (i = 0; i < 100000; i++)
__asm__("nop");
while (true) {
adns3080_write(0x13, 0x83);
for (i = 0; i < 20000; i++)
__asm__("nop");
usart_send_blocking(USART1, 0xff);
usart_send_blocking(USART1, 0xff);
usart_send_blocking(USART1, 0xff);
usart_send_blocking(USART1, 0xff);
for (i = 0; i < 900; i++)
usart_send_blocking(USART1, adns3080_read(0x13) & 0x3f);
gpio_toggle(GPIOB, GPIO7);
}
return 0;
}