diff options
| author | spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> | 2022-02-09 22:59:16 +0100 |
|---|---|---|
| committer | spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> | 2022-02-09 22:59:16 +0100 |
| commit | aca79b2a75c9a6106bc0047f767a475a2c3aaf8e (patch) | |
| tree | a9536efe30ce2d3a40414948494a0eda3e45dbbd /examples/io/pads/spi.c | |
| parent | c083d3f18ecf80297b45eeda2abdf2fd6719cd7b (diff) | |
| download | psn00bsdk-aca79b2a75c9a6106bc0047f767a475a2c3aaf8e.tar.gz | |
Rename hwregs_a definitions, add hwregs_c, fix io/pads
Diffstat (limited to 'examples/io/pads/spi.c')
| -rw-r--r-- | examples/io/pads/spi.c | 103 |
1 files changed, 46 insertions, 57 deletions
diff --git a/examples/io/pads/spi.c b/examples/io/pads/spi.c index ef75ffc..05a0e59 100644 --- a/examples/io/pads/spi.c +++ b/examples/io/pads/spi.c @@ -32,43 +32,27 @@ #include <psxetc.h> #include <psxapi.h> #include <psxpad.h> +#include <hwregs_c.h> #include "spi.h" -/* Register definitions */ - -#define F_CPU 33868800UL - -#define TIM_VALUE(N) *((volatile uint32_t *) 0x1f801100 + 4 * (N)) -#define TIM_CTRL(N) *((volatile uint32_t *) 0x1f801104 + 4 * (N)) -#define TIM_RELOAD(N) *((volatile uint32_t *) 0x1f801108 + 4 * (N)) - -// IMPORTANT: even though JOY_TXRX is a 32-bit register, it should only be -// accessed as 8-bit. Reading it as 16 or 32-bit works fine on real hardware, -// but leads to problems in some emulators. -#define JOY_TXRX *((volatile uint8_t *) 0x1f801040) -#define JOY_STAT *((volatile uint16_t *) 0x1f801044) -#define JOY_MODE *((volatile uint16_t *) 0x1f801048) -#define JOY_CTRL *((volatile uint16_t *) 0x1f80104a) -#define JOY_BAUD *((volatile uint16_t *) 0x1f80104e) - /* Internal structures and globals */ -typedef struct _SPI_CONTEXT { +typedef struct _SPI_Context { uint8_t tx_buff[SPI_BUFF_LEN]; uint8_t rx_buff[SPI_BUFF_LEN]; uint32_t tx_len, rx_len, port; SPI_Callback callback; } SPI_Context; -static volatile SPI_Context ctx; -static volatile SPI_Request volatile *current_req; -static SPI_Callback default_cb; +static volatile SPI_Context _context; +static volatile SPI_Request volatile *_current_req; +static volatile SPI_Callback _default_cb; /* Request queue management */ static void _spi_create_poll_req(void) { - PadRequest *req = (PadRequest *) ctx.tx_buff; + PadRequest *req = (PadRequest *) _context.tx_buff; req->addr = 0x01; req->cmd = PAD_CMD_READ; @@ -76,27 +60,31 @@ static void _spi_create_poll_req(void) { req->motor_l = 0x00; req->motor_r = 0x00; - ctx.tx_len = 4; - ctx.rx_len = 0; - ctx.port ^= 1; - ctx.callback = default_cb; + _context.tx_len = 4; + _context.rx_len = 0; + _context.port ^= 1; + _context.callback = _default_cb; } static void _spi_next_req(void) { // Copy the contents of the first request in the queue into the TX buffer. - memcpy((void *) ctx.tx_buff, (void *) current_req->data, current_req->len); + memcpy( + (void *) _context.tx_buff, + (void *) _current_req->data, + _current_req->len + ); - ctx.tx_len = current_req->len; - ctx.rx_len = 0; - ctx.port = current_req->port; - ctx.callback = current_req->callback; + _context.tx_len = _current_req->len; + _context.rx_len = 0; + _context.port = _current_req->port; + _context.callback = _current_req->callback; // Pop the first request from the queue by deallocating it and adjusting // the pointer to the first queue item. - SPI_Request *next = current_req->next; + SPI_Request *next = _current_req->next; - free((void *) current_req); - current_req = next; + free((void *) _current_req); + _current_req = next; } /* Interrupt handlers */ @@ -105,13 +93,13 @@ static void _spi_poll_irq_handler(void) { // Fetch the last response byte, which wasn't followed by a pulse on /ACK, // from the RX FIFO. if (JOY_STAT & 0x0002) - ctx.rx_buff[ctx.rx_len - 1] = (uint8_t) JOY_TXRX; + _context.rx_buff[_context.rx_len - 1] = (uint8_t) JOY_TXRX; - if (ctx.callback) - ctx.callback(ctx.port, ctx.rx_buff, ctx.rx_len); + if (_context.callback) + _context.callback(_context.port, _context.rx_buff, _context.rx_len); // If the request queue is empty, create a pad polling request. - if (current_req) + if (_current_req) _spi_next_req(); else _spi_create_poll_req(); @@ -119,17 +107,18 @@ static void _spi_poll_irq_handler(void) { // Prepare the SPI port by clearing any pending IRQ, pulling /CS high and // enabling the /ACK IRQ. In order to communicate with controllers, /CS has // to be driven low again for about 20 us before sending the first byte. + // TODO: these delays can be probably tweaked for better performance JOY_CTRL = 0x0010; - for (uint32_t i = 0; i < 50; i++) - __asm__("nop"); + for (uint32_t i = 0; i < 1000; i++) + __asm__ volatile(""); - JOY_CTRL = 0x1003 | (ctx.port << 13); - for (uint32_t i = 0; i < 500; i++) - __asm__("nop"); + JOY_CTRL = 0x1003 | (_context.port << 13); + for (uint32_t i = 0; i < 2000; i++) + __asm__ volatile(""); // Send the first byte indicating which device to address. If the matching // device is connected, it will reply by triggering the /ACK IRQ. - JOY_TXRX = ctx.tx_buff[0]; + JOY_TXRX = _context.tx_buff[0]; } static void _spi_ack_irq_handler(void) { @@ -137,29 +126,29 @@ static void _spi_ack_irq_handler(void) { // byte. According to nocash docs, this has to be done before resetting the // IRQ. while (JOY_STAT & 0x0080) - __asm__("nop"); + __asm__ volatile(""); // Keep /CS pulled low and acknowledge the IRQ (bit 4) to ensure it can be // triggered again. - JOY_CTRL = 0x1013 | (ctx.port << 13); + JOY_CTRL = 0x1013 | (_context.port << 13); - if (!ctx.rx_len) { + if (!_context.rx_len) { // We just sent the first address byte. Obviously the response we // received was read from an open bus, so the SPI port's internal FIFO // must be flushed (by performing dummy reads) to ensure we are only // going to read valid data from now on. JOY_TXRX; - } else if (ctx.rx_len <= SPI_BUFF_LEN) { + } else if (_context.rx_len <= SPI_BUFF_LEN) { // If this is not the first byte, put it in the RX buffer. - ctx.rx_buff[ctx.rx_len - 1] = (uint8_t) JOY_TXRX; + _context.rx_buff[_context.rx_len - 1] = (uint8_t) JOY_TXRX; } // Send the next byte, or a null byte if there is no more data to send and // we're just reading a response. - ctx.rx_len++; - if (ctx.rx_len < ctx.tx_len) - JOY_TXRX = (uint32_t) ctx.tx_buff[ctx.rx_len]; + _context.rx_len++; + if (_context.rx_len < _context.tx_len) + JOY_TXRX = (uint32_t) _context.tx_buff[_context.rx_len]; else JOY_TXRX = 0x00; } @@ -176,10 +165,10 @@ SPI_Request *SPI_CreateRequest(void) { // Find the last queued request by traversing the linked list and append a // pointer to the new request. - if (!current_req) { - current_req = req; + if (!_current_req) { + _current_req = req; } else { - volatile SPI_Request *volatile last = current_req; + volatile SPI_Request *volatile last = _current_req; while (last->next) last = last->next; @@ -213,6 +202,6 @@ void SPI_Init(SPI_Callback callback) { JOY_BAUD = 0x0088; // 250000 bps SPI_SetPollRate(250); - current_req = 0; - default_cb = callback; + _current_req = 0; + _default_cb = callback; } |
