/* * This file is part of the libopencm3 project. * * Copyright (C) 2009 Uwe Hermann * Copyright (C) 2013 Stephen Dwyer * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ #include #include #include #include #include #include #include #include int _write(int file, char *ptr, int len); static void clock_setup(void) { rcc_clock_setup_in_hse_12mhz_out_72mhz(); /* Enable GPIOA, GPIOB, GPIOC clock. */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN); /* Enable clocks for GPIO port A (for GPIO_USART2_TX) and USART2. */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); /* Enable SPI1 Periph and gpio clocks */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SPI1EN); } static void spi_setup(void) { /* Configure GPIOs: SS=PA4, SCK=PA5, MISO=PA6 and MOSI=PA7 */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4 | GPIO5 | GPIO7 ); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO6); /* Reset SPI, SPI_CR1 register cleared, SPI is disabled */ spi_reset(SPI1); /* Set up SPI in Master mode with: * Clock baud rate: 1/64 of peripheral clock frequency * Clock polarity: Idle High * Clock phase: Data valid on 2nd clock pulse * Data frame format: 8-bit * Frame format: MSB First */ 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); /* * Set NSS management to software. * * Note: * Setting nss high is very important, even if we are controlling the GPIO * ourselves this bit needs to be at least set to 1, otherwise the spi * peripheral will not send any data out. */ spi_enable_software_slave_management(SPI1); spi_set_nss_high(SPI1); /* Enable SPI1 periph. */ spi_enable(SPI1); } static void usart_setup(void) { /* Setup GPIO pin GPIO_USART2_TX and GPIO_USART2_RX. */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX); /* Setup UART parameters. */ usart_set_baudrate(USART2, 9600); usart_set_databits(USART2, 8); usart_set_stopbits(USART2, USART_STOPBITS_1); usart_set_mode(USART2, USART_MODE_TX_RX); usart_set_parity(USART2, USART_PARITY_NONE); usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); /* Finally enable the USART. */ usart_enable(USART2); } int _write(int file, char *ptr, int len) { int i; if (file == 1) { for (i = 0; i < len; i++) usart_send_blocking(USART2, ptr[i]); return i; } errno = EIO; return -1; } static void gpio_setup(void) { /* Set GPIO8 (in GPIO port A) to 'output push-pull'. */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); } int main(void) { int counter = 0; u16 rx_value = 0x42; clock_setup(); gpio_setup(); usart_setup(); spi_setup(); /* Blink the LED (PA8) on the board with every transmitted byte. */ while (1) { /* LED on/off */ gpio_toggle(GPIOA, GPIO8); /* printf the value that SPI should send */ printf("Counter: %i SPI Sent Byte: %i", counter, (uint8_t) counter); /* blocking send of the byte out SPI1 */ spi_send(SPI1, (uint8_t) counter); /* Read the byte that just came in (use a loopback between MISO and MOSI * to get the same byte back) */ rx_value = spi_read(SPI1); /* printf the byte just received */ printf(" SPI Received Byte: %i\r\n", rx_value); counter++; } return 0; }