Updating docs

This commit is contained in:
Adam Greenwood-Byrne 2021-11-07 19:29:45 +00:00
parent 787e6ec8cb
commit dfc89a4449
4 changed files with 15 additions and 36 deletions

View file

@ -40,9 +40,16 @@ Let's start by looking at how we implement SPI communication.
I'm not going to write a long paper on how SPI works and why we need it, because it's [very well documented elsewhere](https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/). It's recommended background reading, but not essential if all you want to do is get something working. I'm not going to write a long paper on how SPI works and why we need it, because it's [very well documented elsewhere](https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/). It's recommended background reading, but not essential if all you want to do is get something working.
Look at _lib/spi.c_. It uses some of existing functions in _lib/io.c_ that you'll remember from earlier tutorials. Specifically, _spi_init()_ sets GPIO 7, 9, 10, and 11 to use the ALT0 function. Cross-referencing with the [BCM2711 ARM Peripherals document](https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf), page 77, you'll see that this maps SPI0 to the GPIO header. GPIO 8 is mapped as an output pin, since we'll use this to signal to the ENC28J60 that we want to talk. In fact, the _spi_chip_select()_ function takes a true/false (boolean) parameter which either sets or clears this pin. Look at _lib/spi.c_. It uses some of existing functions in _lib/io.c_ that you'll remember from earlier tutorials. In fact, I've added two functions to the _include/io.h_ header file so we can call them from our SPI library:
Looking at the SPI0 register map on page 134, we see this reflected in the _REGS_SPI0_ structure. This gives us handy access to the SPI0 peripheral's memory map. ```c
void gpio_setPinOutputBool(unsigned int pin_number, unsigned int onOrOff);
void gpio_initOutputPinWithPullNone(unsigned int pin_number);
```
Specifically, _spi_init()_ sets GPIO 7, 9, 10, and 11 to use the ALT0 function. Cross-referencing with the [BCM2711 ARM Peripherals document](https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf), page 77, you'll see that this maps SPI0 to the GPIO header. GPIO 8 is mapped as an output pin, since we'll use this to signal to the ENC28J60 that we want to talk. In fact, the _spi_chip_select()_ function takes a true/false (boolean) parameter which either sets or clears this pin.
Looking at the SPI0 register map on page 134, we see this reflected in our _REGS_SPI0_ structure. This gives us handy access to the SPI0 peripheral's memory-mapped registers.
Our _spi_send_recv()_ function then sets us up for some communcation: Our _spi_send_recv()_ function then sets us up for some communcation:
@ -54,4 +61,4 @@ Then, whilst there's either data to write or data to read (and we haven't writte
Finally, to be absolutely sure, we clear the TA flag. Finally, to be absolutely sure, we clear the TA flag.
I've then set up two convenient functions _spi_send()_ and _spi_recv()_ which exercise _spi_send_recv(), mainly to make future code more readable. I've then set up two convenient functions - _spi_send()_ and _spi_recv()_ - which exercise _spi_send_recv(), mainly to make future code more readable.

View file

@ -2,5 +2,4 @@ void spi_init();
void spi_send_recv(unsigned char *sbuffer, unsigned char *rbuffer, unsigned int size); void spi_send_recv(unsigned char *sbuffer, unsigned char *rbuffer, unsigned int size);
void spi_send(unsigned char *data, unsigned int size); void spi_send(unsigned char *data, unsigned int size);
void spi_recv(unsigned char *data, unsigned int size); void spi_recv(unsigned char *data, unsigned int size);
void spi_send_no_selection(unsigned char command);
void spi_chip_select(unsigned char chip_select); void spi_chip_select(unsigned char chip_select);

View file

@ -1,27 +1,4 @@
#include "kernel.h" #include "kernel.h"
#include "../include/fb.h"
char *entry_error_messages[] = {
"SYNC_INVALID_EL1t",
"IRQ_INVALID_EL1t",
"FIQ_INVALID_EL1t",
"ERROR_INVALID_EL1T",
"SYNC_INVALID_EL1h",
"IRQ_INVALID_EL1h",
"FIQ_INVALID_EL1h",
"ERROR_INVALID_EL1h",
"SYNC_INVALID_EL0_64",
"IRQ_INVALID_EL0_64",
"FIQ_INVALID_EL0_64",
"ERROR_INVALID_EL0_64",
"SYNC_INVALID_EL0_32",
"IRQ_INVALID_EL0_32",
"FIQ_INVALID_EL0_32",
"ERROR_INVALID_EL0_32"
};
void enable_interrupt_controller() { void enable_interrupt_controller() {
REGS_IRQ->irq0_enable_0 = SYS_TIMER_IRQ_1 | SYS_TIMER_IRQ_3; REGS_IRQ->irq0_enable_0 = SYS_TIMER_IRQ_1 | SYS_TIMER_IRQ_3;
@ -31,14 +8,6 @@ void disable_interrupt_controller() {
REGS_IRQ->irq0_enable_0 = 0; REGS_IRQ->irq0_enable_0 = 0;
} }
void show_invalid_entry_message(int type, unsigned long esr, unsigned long address) {
debugstr(entry_error_messages[type]);
debugstr(" ESR: ");
debughex(esr);
debugstr("Addr: ");
debughex(address);
}
void handle_irq() { void handle_irq() {
unsigned int irq = REGS_IRQ->irq0_pending_0; unsigned int irq = REGS_IRQ->irq0_pending_0;

View file

@ -67,7 +67,11 @@
mov x0, #\type mov x0, #\type
mrs x1, esr_el1 mrs x1, esr_el1
mrs x2, elr_el1 mrs x2, elr_el1
bl show_invalid_entry_message
// We could pass this to a function to print an error here
// e.g. bl show_invalid_entry_message
//
// For now we'll just hang
b err_hang b err_hang
.endm .endm