diff --git a/part14-spi-ethernet/README.md b/part14-spi-ethernet/README.md index c89cba6..e575ba2 100644 --- a/part14-spi-ethernet/README.md +++ b/part14-spi-ethernet/README.md @@ -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. -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: @@ -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. -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. diff --git a/part14-spi-ethernet/include/spi.h b/part14-spi-ethernet/include/spi.h index c5fca8b..bf57e3e 100644 --- a/part14-spi-ethernet/include/spi.h +++ b/part14-spi-ethernet/include/spi.h @@ -2,5 +2,4 @@ void spi_init(); void spi_send_recv(unsigned char *sbuffer, unsigned char *rbuffer, unsigned int size); void spi_send(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); diff --git a/part14-spi-ethernet/kernel/irq.c b/part14-spi-ethernet/kernel/irq.c index bc2276a..3ab82d1 100644 --- a/part14-spi-ethernet/kernel/irq.c +++ b/part14-spi-ethernet/kernel/irq.c @@ -1,27 +1,4 @@ #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() { 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; } -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() { unsigned int irq = REGS_IRQ->irq0_pending_0; diff --git a/part14-spi-ethernet/kernel/irqentry.S b/part14-spi-ethernet/kernel/irqentry.S index 28d0b94..d24ae00 100644 --- a/part14-spi-ethernet/kernel/irqentry.S +++ b/part14-spi-ethernet/kernel/irqentry.S @@ -67,7 +67,11 @@ mov x0, #\type mrs x1, esr_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 .endm