mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
SPI data registers
This commit is contained in:
4
Makefile
4
Makefile
@@ -35,9 +35,9 @@ boot.bin: boot.elf
|
||||
@echo "OBJCOPY $@"
|
||||
@$(OBJCOPY) -O binary boot.elf boot.bin
|
||||
|
||||
boot.elf: $(objs) src/spi.o
|
||||
boot.elf: $(objs) src/lcd_spi.o
|
||||
@echo "LD $@"
|
||||
@$(LD) -T boot/stm32f429.ld $(objs) src/spi.o -o $@
|
||||
@$(LD) -T boot/stm32f429.ld $(objs) src/lcd_spi.o -o $@
|
||||
|
||||
%.o: %.c
|
||||
@echo "CC $@"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#define SPI_CR1_OFFSET 0x00
|
||||
#define SPI_SR_OFFSET 0x08
|
||||
#define SPI_DR_OFFSET 0x0C
|
||||
|
||||
char * SPI_REGISTER_ADDRESS(SPI_t spi, int registerOffset) {
|
||||
char * spiBaseAddress[6] = {
|
||||
@@ -25,3 +26,7 @@ SPI_CR1_t * SPI_CR1(SPI_t spi) {
|
||||
SPI_SR_t * SPI_SR(SPI_t spi) {
|
||||
return (SPI_SR_t *)SPI_REGISTER_ADDRESS(spi, SPI_SR_OFFSET);
|
||||
}
|
||||
|
||||
SPI_DR_t * SPI_DR(SPI_t spi) {
|
||||
return (SPI_DR_t *)SPI_REGISTER_ADDRESS(spi, SPI_DR_OFFSET);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
SPI1 = 0,
|
||||
SPI2 = 1,
|
||||
@@ -25,7 +27,6 @@ typedef enum {
|
||||
SPI_DFF_16_BITS = 1
|
||||
} SPI_DFF_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int CPHA:1;
|
||||
unsigned int CPOL:1;
|
||||
@@ -61,3 +62,8 @@ typedef struct {
|
||||
} SPI_SR_t;
|
||||
|
||||
SPI_SR_t * SPI_SR(SPI_t spi);
|
||||
|
||||
#pragma mark - SPI data registers
|
||||
|
||||
typedef uint16_t SPI_DR_t;
|
||||
SPI_DR_t * SPI_DR(SPI_t spi);
|
||||
|
||||
101
src/lcd_spi.c
Normal file
101
src/lcd_spi.c
Normal file
@@ -0,0 +1,101 @@
|
||||
#include <registers.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <timers.h>
|
||||
#include <semphr.h>
|
||||
|
||||
/* This code sends data to the onboard LCD over SPI
|
||||
*
|
||||
* The LCD has two interfaces, SPI and direct RGB.
|
||||
* We'll only use SPI in this one.
|
||||
*
|
||||
* The documentation gives the following mapping
|
||||
* Pin name - LCD-SPI
|
||||
* NRST - Reset
|
||||
* PC2 - CSX // Chip select for LCD
|
||||
* PD13 - DCX // Data/Command register
|
||||
* PF7 - SCL // SPI Clock
|
||||
* PF9 - SDI/SDO // MOSI
|
||||
*
|
||||
* See UM1670 p. 19 to 24. */
|
||||
|
||||
/* We'll need to figure out which GPIO pins this maps to, and in which
|
||||
* Alternate Function mode. STM32F429 datasheet p78-79 says:
|
||||
* PF6 in AF5 = SPI5_NSS
|
||||
* PF7 in AF5 = SPI5_SCK
|
||||
* PF8 in AF5 = SPI5_MISO
|
||||
* PF9 in AF5 = SPI5_MOSI
|
||||
*/
|
||||
|
||||
/* In case we want to monitor this, here's a color-mapping
|
||||
*
|
||||
* PF6 - SPI5_NSS - Yellow
|
||||
* PF7 - SPI5_SCK - Green
|
||||
* PF8 - SPI5_MISO - Red
|
||||
* PF9 - SPI5_MOSI - Blue
|
||||
*/
|
||||
|
||||
void SpiSend(void * pvParameters) {
|
||||
uint16_t value = 0;
|
||||
while(1) {
|
||||
SPI_SR_t * spi_status = SPI_SR(SPI5);
|
||||
SPI_DR_t * spi_data_register = SPI_DR(SPI5);
|
||||
if (spi_status->BSY == 0) {
|
||||
*spi_data_register = value++;
|
||||
}
|
||||
vTaskDelay(100/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
// We'll use GPIO pins F6-F9 to emit SPI data
|
||||
// GPIO are grouped by letter. All GPIO groups live on the "AHB1" bus.
|
||||
// (this is documented in the STM32F4 reference mnual, page 65)
|
||||
|
||||
// Step 1 : Enable clock in RCC_AHBxENR
|
||||
RCC_AHB1ENR->GPIOFEN = 1;
|
||||
|
||||
// Step 2 : Configure the GPIO pin to "Alternate function number 5"
|
||||
// This means "SPI5 on pins F6-F9", cf STM32F249 p78
|
||||
GPIO_MODER(GPIOF)->MODER6 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
GPIO_MODER(GPIOF)->MODER7 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
GPIO_MODER(GPIOF)->MODER8 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
GPIO_MODER(GPIOF)->MODER9 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
|
||||
// We're interested in pins 11-14, which are in the 8-16 range, so we
|
||||
// have to deal with the "high" version of the AF register
|
||||
GPIO_AFRL(GPIOF)->AFRL6 = GPIO_AF_AF5;
|
||||
GPIO_AFRL(GPIOF)->AFRL7 = GPIO_AF_AF5;
|
||||
GPIO_AFRH(GPIOF)->AFRH8 = GPIO_AF_AF5;
|
||||
GPIO_AFRH(GPIOF)->AFRH9 = GPIO_AF_AF5;
|
||||
|
||||
// Enable the SPI5 clock
|
||||
RCC_APB2ENR->SPI5EN = 1;
|
||||
|
||||
// Configure the SPI port
|
||||
// Using a C99 compound litteral. C99 guarantees all non-set values are zero
|
||||
*SPI_CR1(SPI5) = (SPI_CR1_t){
|
||||
.BIDIMODE = 1,
|
||||
.BIDIOE = 1,
|
||||
.MSTR = 1,
|
||||
.DFF = SPI_DFF_16_BITS,
|
||||
.CPOL = 0,
|
||||
.BR = SPI_BR_DIV_256,
|
||||
.SSM = 1,
|
||||
.SSI = 1,
|
||||
.SPE = 1
|
||||
};
|
||||
|
||||
BaseType_t success = xTaskCreate(SpiSend,
|
||||
"SpiSnd",
|
||||
100, // Stack size
|
||||
NULL, // Parameters
|
||||
2,
|
||||
NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
while (1) {
|
||||
// We should never get here
|
||||
}
|
||||
}
|
||||
49
src/spi.c
49
src/spi.c
@@ -51,43 +51,18 @@ int main(int argc, char * argv[]) {
|
||||
RCC_APB2ENR->SPI4EN = 1;
|
||||
|
||||
// Configure the SPI port
|
||||
/*
|
||||
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
|
||||
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
|
||||
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
|
||||
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
|
||||
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
|
||||
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
|
||||
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
*/
|
||||
SPI_CR1_t * SPI4_CR1 = SPI_CR1(SPI4);
|
||||
/*
|
||||
SPI4_CR1->BIDIMODE = 0;
|
||||
SPI4_CR1->BIDIOE = 1;
|
||||
SPI4_CR1->MSTR = 1;
|
||||
SPI4_CR1->DFF = SPI_DFF_8_BITS;
|
||||
SPI4_CR1->CPOL = 0;
|
||||
SPI4_CR1->BR = SPI_BR_DIV_256;
|
||||
SPI4_CR1->SSM = 1;
|
||||
SPI4_CR1->SSI = 1;
|
||||
SPI4_CR1->SPE = 1;
|
||||
*/
|
||||
|
||||
/*
|
||||
11 0 0 1
|
||||
0 1 1 0 1 111
|
||||
100 */
|
||||
|
||||
/*
|
||||
* 1100
|
||||
* 1011
|
||||
* 0111
|
||||
* 1100
|
||||
*/
|
||||
*(uint16_t *)SPI4_CR1 = 0xCB7C;
|
||||
|
||||
SPI_CR1_t output = *SPI4_CR1;
|
||||
// Using a C99 compound litteral
|
||||
*SPI_CR1(SPI4) = (SPI_CR1_t){
|
||||
.BIDIMODE = 1,
|
||||
.BIDIOE = 1,
|
||||
.MSTR = 1,
|
||||
.DFF = SPI_DFF_16_BITS,
|
||||
.CPOL = 0,
|
||||
.BR = SPI_BR_DIV_256,
|
||||
.SSM = 1,
|
||||
.SSI = 1,
|
||||
.SPE = 1
|
||||
};
|
||||
|
||||
BaseType_t success = xTaskCreate(SpiSend,
|
||||
"SpiSnd",
|
||||
|
||||
Reference in New Issue
Block a user