You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/07/10 13:49:42 UTC
[GitHub] andrzej-kaczmarek closed pull request #1252: hw/mcu/nordic:
Improvements for SPIM on nRF52xxx
andrzej-kaczmarek closed pull request #1252: hw/mcu/nordic: Improvements for SPIM on nRF52xxx
URL: https://github.com/apache/mynewt-core/pull/1252
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_spi.c b/hw/mcu/nordic/nrf52xxx/src/hal_spi.c
index 5df4afabfd..21aee41bf4 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_spi.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_spi.c
@@ -30,6 +30,12 @@
#define min(a, b) ((a)<(b)?(a):(b))
#endif
+#ifdef NRF52840_XXAA
+#define SPIM_TXD_MAXCNT_MAX 65535
+#else
+#define SPIM_TXD_MAXCNT_MAX 255
+#endif
+
/* IRQ handler type */
typedef void (*nrf52_spi_irq_handler_t)(void);
@@ -64,8 +70,6 @@ struct nrf52_hal_spi
uint8_t spi_xfr_flag; /* Master only */
uint8_t dummy_rx; /* Master only */
uint8_t slave_state; /* Slave only */
- uint16_t nhs_buflen;
- uint16_t nhs_bytes_txd;
struct hal_spi_settings spi_cfg; /* Slave and master */
/* Pointer to HW registers */
@@ -77,9 +81,10 @@ struct nrf52_hal_spi
/* IRQ number */
IRQn_Type irq_num;
- /* Pointers to tx/rx buffers */
- uint8_t *nhs_txbuf;
- uint8_t *nhs_rxbuf;
+ uint8_t *nhs_txbuf; /* Pointer to TX buffer */
+ uint8_t *nhs_rxbuf; /* Pointer to RX buffer */
+ uint16_t nhs_buflen; /* Length of buffer */
+ uint16_t nhs_bytes_txq; /* Number of bytes queued for TX */
/* Callback and arguments */
hal_spi_txrx_cb txrx_cb_func;
@@ -129,43 +134,61 @@ static const struct nrf52_hal_spi *nrf52_hal_spis[NRF52_HAL_SPI_MAX] = {
static void
nrf52_irqm_handler(struct nrf52_hal_spi *spi)
{
- uint8_t xfr_bytes;
- uint16_t len;
NRF_SPIM_Type *spim;
+ uint16_t xfr_bytes;
+ uint16_t next_len;
spim = spi->nhs_spi.spim;
- if (spim->EVENTS_END) {
- spim->EVENTS_END = 0;
- /* Should not occur but if no transfer just leave */
- if (spi->spi_xfr_flag == 0) {
- return;
- }
+ /* Should not occur but if no transfer just leave */
+ if (spi->spi_xfr_flag == 0) {
+ return;
+ }
+
+ if ((spim->EVENTS_STARTED) && (spim->INTENSET & SPIM_INTENSET_STARTED_Msk)) {
+ spim->EVENTS_STARTED = 0;
- /* Are there more bytes to send? */
- xfr_bytes = spim->TXD.AMOUNT;
- spi->nhs_bytes_txd += xfr_bytes;
- if (spi->nhs_bytes_txd < spi->nhs_buflen) {
+ xfr_bytes = spim->TXD.MAXCNT;
+ spi->nhs_bytes_txq += xfr_bytes;
+
+ if (spi->nhs_bytes_txq < spi->nhs_buflen) {
spi->nhs_txbuf += xfr_bytes;
- len = spi->nhs_buflen - spi->nhs_bytes_txd;
- len = min(255, len);
+
+ next_len = min(SPIM_TXD_MAXCNT_MAX,
+ spi->nhs_buflen - spi->nhs_bytes_txq);
+
spim->TXD.PTR = (uint32_t)spi->nhs_txbuf;
- spim->TXD.MAXCNT = (uint8_t)len;
+ spim->TXD.MAXCNT = next_len;
- /* If no rxbuf, we need to set rxbuf and maxcnt to 1 */
+ /* If no RX buffer was provided, we already set it to dummy one */
if (spi->nhs_rxbuf) {
spi->nhs_rxbuf += xfr_bytes;
- spim->RXD.PTR = (uint32_t)spi->nhs_rxbuf;
- spim->RXD.MAXCNT = (uint8_t)len;
+ spim->RXD.PTR = (uint32_t)spi->nhs_rxbuf;
+ spim->RXD.MAXCNT = next_len;
}
- spim->TASKS_START = 1;
+
+ spim->SHORTS |= SPIM_SHORTS_END_START_Msk;
+ spim->INTENSET = SPIM_INTENSET_STARTED_Msk;
+ spim->INTENCLR = SPIM_INTENSET_END_Msk;
} else {
+ spim->SHORTS &= ~SPIM_SHORTS_END_START_Msk;
+ spim->INTENSET = SPIM_INTENSET_END_Msk;
+ spim->INTENCLR = SPIM_INTENSET_STARTED_Msk;
+ }
+ }
+
+ if (spim->EVENTS_END) {
+ spim->EVENTS_END = 0;
+
+ if (spim->INTENSET & SPIM_INTENSET_END_Msk) {
if (spi->txrx_cb_func) {
spi->txrx_cb_func(spi->txrx_cb_arg, spi->nhs_buflen);
-
}
+
spi->spi_xfr_flag = 0;
- spim->INTENCLR = SPIM_INTENSET_END_Msk;
+
+ spim->SHORTS &= ~SPIM_SHORTS_END_START_Msk;
+ spim->INTENCLR = SPIM_INTENSET_STARTED_Msk | SPIM_INTENSET_END_Msk;
}
}
}
@@ -441,7 +464,7 @@ hal_spi_init_master(struct nrf52_hal_spi *spi,
}
port->PIN_CNF[pin] =
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
- (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos);
+ (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
/* Configure MOSI */
port = HAL_GPIO_PORT(cfg->mosi_pin);
@@ -758,7 +781,7 @@ hal_spi_disable(int spi_num)
spi->nhs_txbuf = NULL;
spi->nhs_rxbuf = NULL;
spi->nhs_buflen = 0;
- spi->nhs_bytes_txd = 0;
+ spi->nhs_bytes_txq = 0;
rc = 0;
@@ -1011,10 +1034,12 @@ hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int len)
}
/* Set internal data structure information */
- spi->nhs_bytes_txd = 0;
+ spi->nhs_bytes_txq = 0;
spi->nhs_buflen = len;
spi->nhs_txbuf = txbuf;
+ len = min(SPIM_TXD_MAXCNT_MAX, len);
+
/* Set chip registers */
spim->TXD.PTR = (uint32_t)txbuf;
spim->TXD.MAXCNT = len;
@@ -1031,8 +1056,15 @@ hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int len)
spim->EVENTS_END = 0;
spim->EVENTS_STOPPED = 0;
+ spim->EVENTS_STARTED = 0;
+ if (spi->nhs_buflen < 256) {
+ spim->INTENCLR = SPIM_INTENSET_STARTED_Msk;
+ spim->INTENSET = SPIM_INTENSET_END_Msk;
+ } else {
+ spim->INTENCLR = SPIM_INTENSET_END_Msk;
+ spim->INTENSET = SPIM_INTENSET_STARTED_Msk;
+ }
spim->TASKS_START = 1;
- spim->INTENSET = SPIM_INTENSET_END_Msk;
} else {
/* Must have txbuf or rxbuf */
if ((txbuf == NULL) && (rxbuf == NULL)) {
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services