mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-29 14:52:12 +01:00
OP-932: Hold SPI bus semephore through multiple read/write transactions.
This commit is contained in:
parent
8c59271d48
commit
cb24d3266e
@ -206,9 +206,9 @@ static void rfm22_assertCs(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_deassertCs(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_claimBus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_releaseBus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_write_claim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data);
|
||||
static void rfm22_write(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data);
|
||||
static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr);
|
||||
static uint8_t rfm22_read_noclaim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr);
|
||||
|
||||
|
||||
/* The state transition table */
|
||||
@ -1065,7 +1065,7 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->rx_complete_ticks = 0;
|
||||
|
||||
// software reset the RF chip .. following procedure according to Si4x3x Errata (rev. B)
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_swres);
|
||||
rfm22_write_claim(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_swres);
|
||||
|
||||
for (uint8_t i = 0; i < 50; ++i) {
|
||||
|
||||
@ -1085,6 +1085,9 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
// read status - clears interrupt
|
||||
rfm22_readStatus(rfm22b_dev);
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// disable all interrupts
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
@ -1181,14 +1184,14 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
|
||||
// header control - using a 4 by header with broadcast of 0xffffffff
|
||||
rfm22_write(rfm22b_dev, RFM22_header_control1,
|
||||
RFM22_header_cntl1_bcen_0 |
|
||||
RFM22_header_cntl1_bcen_1 |
|
||||
RFM22_header_cntl1_bcen_2 |
|
||||
RFM22_header_cntl1_bcen_3 |
|
||||
RFM22_header_cntl1_hdch_0 |
|
||||
RFM22_header_cntl1_hdch_1 |
|
||||
RFM22_header_cntl1_hdch_2 |
|
||||
RFM22_header_cntl1_hdch_3);
|
||||
RFM22_header_cntl1_bcen_0 |
|
||||
RFM22_header_cntl1_bcen_1 |
|
||||
RFM22_header_cntl1_bcen_2 |
|
||||
RFM22_header_cntl1_bcen_3 |
|
||||
RFM22_header_cntl1_hdch_0 |
|
||||
RFM22_header_cntl1_hdch_1 |
|
||||
RFM22_header_cntl1_hdch_2 |
|
||||
RFM22_header_cntl1_hdch_3);
|
||||
// Check all bit of all bytes of the header
|
||||
rfm22_write(rfm22b_dev, RFM22_header_enable0, 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_header_enable1, 0xff);
|
||||
@ -1202,9 +1205,9 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22_write(rfm22b_dev, RFM22_check_header3, (id >> 24) & 0xff);
|
||||
// 4 header bytes, synchronization word length 3, 2, 1 & 0 used, packet length included in header.
|
||||
rfm22_write(rfm22b_dev, RFM22_header_control2,
|
||||
RFM22_header_cntl2_hdlen_3210 |
|
||||
RFM22_header_cntl2_synclen_3210 |
|
||||
((TX_PREAMBLE_NIBBLES >> 8) & 0x01));
|
||||
RFM22_header_cntl2_hdlen_3210 |
|
||||
RFM22_header_cntl2_synclen_3210 |
|
||||
((TX_PREAMBLE_NIBBLES >> 8) & 0x01));
|
||||
|
||||
// sync word
|
||||
rfm22_write(rfm22b_dev, RFM22_sync_word3, SYNC_BYTE_1);
|
||||
@ -1227,6 +1230,9 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
// Set the frequency calibration
|
||||
rfm22_write(rfm22b_dev, RFM22_xtal_osc_load_cap, rfm22b_dev->cfg.RFXtalCap);
|
||||
|
||||
// Release the bus
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
// Initialize the frequency and datarate to te default.
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, rfm22b_dev->init_frequency, rfm22b_dev->init_frequency, RFM22B_FREQUENCY_HOP_STEP_SIZE);
|
||||
rfm22_setDatarate(rfm22b_dev, RFM22B_DEFAULT_RX_DATARATE, true);
|
||||
@ -1256,6 +1262,9 @@ static void rfm22_setDatarate(struct pios_rfm22b_dev *rfm22b_dev, enum rfm22b_da
|
||||
uint8_t random = PIOS_CRC_updateByte(0, (uint8_t)(xTaskGetTickCount() & 0xff)) & 0x03;
|
||||
rfm22b_dev->max_ack_delay = (uint16_t)((float)((sizeof(PHAckNackPacket) * 8 + TX_PREAMBLE_NIBBLES * 4) * 1000) / (float)(datarate_bps) + 0.5) * 4 + 4 + random;
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// rfm22_if_filter_bandwidth
|
||||
rfm22_write(rfm22b_dev, 0x1C, reg_1C[datarate]);
|
||||
|
||||
@ -1308,6 +1317,9 @@ static void rfm22_setDatarate(struct pios_rfm22b_dev *rfm22b_dev, enum rfm22b_da
|
||||
|
||||
rfm22_write(rfm22b_dev, RFM22_ook_counter_value1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_ook_counter_value2, 0x00);
|
||||
|
||||
// Release the bus
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1337,6 +1349,9 @@ static void rfm22_setNominalCarrierFrequency(struct pios_rfm22b_dev *rfm22b_dev,
|
||||
uint8_t fch = (fc >> 8) & 0xff;
|
||||
uint8_t fcl = fc & 0xff;
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// Calculate the number of frequency hopping channels.
|
||||
rfm22b_dev->num_channels = (step_size == 0) ? 1 : (uint16_t)((max_frequency - min_frequency) / step_size);
|
||||
|
||||
@ -1362,6 +1377,9 @@ static void rfm22_setNominalCarrierFrequency(struct pios_rfm22b_dev *rfm22b_dev,
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_band_select, fb & 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_nominal_carrier_frequency1, fch);
|
||||
rfm22_write(rfm22b_dev, RFM22_nominal_carrier_frequency0, fcl);
|
||||
|
||||
// Release the bus
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
|
||||
@ -1377,7 +1395,7 @@ static bool rfm22_setFreqHopChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t
|
||||
return false;
|
||||
}
|
||||
rfm22b_dev->frequency_hop_channel = channel;
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_hopping_channel_select, channel);
|
||||
rfm22_write_claim(rfm22b_dev, RFM22_frequency_hopping_channel_select, channel);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1405,10 +1423,10 @@ static bool rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->status_regs.int_status_2.raw = read_buf[2];
|
||||
|
||||
// Device status
|
||||
rfm22b_dev->status_regs.device_status.raw = rfm22_read_noclaim(rfm22b_dev, RFM22_device_status);
|
||||
rfm22b_dev->status_regs.device_status.raw = rfm22_read(rfm22b_dev, RFM22_device_status);
|
||||
|
||||
// EzMAC status
|
||||
rfm22b_dev->status_regs.ezmac_status.raw = rfm22_read_noclaim(rfm22b_dev, RFM22_ezmac_status);
|
||||
rfm22b_dev->status_regs.ezmac_status.raw = rfm22_read(rfm22b_dev, RFM22_ezmac_status);
|
||||
|
||||
// Release the bus
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
@ -1438,6 +1456,9 @@ static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev
|
||||
D2_LED_ON;
|
||||
#endif // PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// disable interrupts
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
@ -1460,13 +1481,16 @@ static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev
|
||||
|
||||
// enable RX interrupts
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, RFM22_ie1_encrcerror | RFM22_ie1_enpkvalid |
|
||||
RFM22_ie1_enrxffafull | RFM22_ie1_enfferr);
|
||||
RFM22_ie1_enrxffafull | RFM22_ie1_enfferr);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, RFM22_ie2_enpreainval | RFM22_ie2_enpreaval |
|
||||
RFM22_ie2_enswdet);
|
||||
RFM22_ie2_enswdet);
|
||||
|
||||
// enable the receiver
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon | RFM22_opfc1_rxon);
|
||||
|
||||
// Release the SPI bus.
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
// Indicate that we're in RX mode.
|
||||
rfm22b_dev->in_rx_mode = true;
|
||||
|
||||
@ -1515,6 +1539,9 @@ static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_de
|
||||
if (rfm22b_dev->status_regs.int_status_2.sync_word_detected) {
|
||||
RX_LED_ON;
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// read the 10-bit signed afc correction value
|
||||
// bits 9 to 2
|
||||
uint16_t afc_correction = (uint16_t)rfm22_read(rfm22b_dev, RFM22_afc_correction_read) << 8;
|
||||
@ -1530,6 +1557,9 @@ static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_de
|
||||
// convert to dBm
|
||||
rfm22b_dev->rssi_dBm = (int8_t)(rssi >> 1) - 122;
|
||||
|
||||
// Release the SPI bus.
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
return RFM22B_EVENT_SYNC_DETECTED;
|
||||
|
||||
}
|
||||
@ -1561,7 +1591,11 @@ static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
// RX FIFO almost full, it needs emptying
|
||||
if (rfm22b_dev->status_regs.int_status_1.rx_fifo_almost_full) {
|
||||
// read data from the rf chips FIFO buffer
|
||||
// read the total length of the packet data
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// Read the total length of the packet data
|
||||
uint16_t len = rfm22_read(rfm22b_dev, RFM22_received_packet_length);
|
||||
|
||||
// The received packet is going to be larger than the specified length
|
||||
@ -1575,17 +1609,21 @@ static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
}
|
||||
|
||||
// Fetch the data from the RX FIFO
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id,RFM22_fifo_access & 0x7F);
|
||||
rfm22b_dev->rx_buffer_wr += (PIOS_SPI_TransferBlock(rfm22b_dev->spi_id ,OUT_FF, (uint8_t *)&rx_buffer[rfm22b_dev->rx_buffer_wr], RX_FIFO_HI_WATERMARK, NULL) == 0) ? RX_FIFO_HI_WATERMARK : 0;
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
|
||||
// Release the SPI bus.
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
// Valid packet received
|
||||
if (rfm22b_dev->status_regs.int_status_1.valid_packet_received) {
|
||||
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// read the total length of the packet data
|
||||
uint32_t len = rfm22_read(rfm22b_dev, RFM22_received_packet_length);
|
||||
|
||||
@ -1593,14 +1631,15 @@ static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
if (rfm22b_dev->rx_buffer_wr < len) {
|
||||
int32_t bytes_to_read = len - rfm22b_dev->rx_buffer_wr;
|
||||
// Fetch the data from the RX FIFO
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id,RFM22_fifo_access & 0x7F);
|
||||
rfm22b_dev->rx_buffer_wr += (PIOS_SPI_TransferBlock(rfm22b_dev->spi_id,OUT_FF, (uint8_t *)&rx_buffer[rfm22b_dev->rx_buffer_wr], bytes_to_read, NULL) == 0) ? bytes_to_read : 0;
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
// Release the SPI bus.
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
if (rfm22b_dev->rx_buffer_wr != len) {
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
}
|
||||
@ -1858,7 +1897,10 @@ static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->packet_start_ticks = 1;
|
||||
}
|
||||
|
||||
// disable interrupts
|
||||
// Claim the SPI bus.
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
|
||||
// Disable interrupts
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
|
||||
@ -1880,21 +1922,18 @@ static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
|
||||
// FIFO mode, GFSK modulation
|
||||
uint8_t fd_bit = rfm22_read(rfm22b_dev, RFM22_modulation_mode_control2) & RFM22_mmc2_fd;
|
||||
rfm22_write(rfm22b_dev, RFM22_modulation_mode_control2, fd_bit | RFM22_mmc2_dtmod_fifo |
|
||||
RFM22_mmc2_modtyp_gfsk);
|
||||
rfm22_write(rfm22b_dev, RFM22_modulation_mode_control2, fd_bit | RFM22_mmc2_dtmod_fifo | RFM22_mmc2_modtyp_gfsk);
|
||||
|
||||
// clear FIFOs
|
||||
// Clear the FIFOs.
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, 0x00);
|
||||
|
||||
// *******************
|
||||
// add some data to the chips TX FIFO before enabling the transmitter
|
||||
|
||||
// set the total number of data bytes we are going to transmit
|
||||
// Set the total number of data bytes we are going to transmit.
|
||||
rfm22_write(rfm22b_dev, RFM22_transmit_packet_length, rfm22b_dev->tx_data_wr);
|
||||
|
||||
// add some data
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
// Add some data.
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id, RFM22_fifo_access | 0x80);
|
||||
int bytes_to_write = (rfm22b_dev->tx_data_wr - rfm22b_dev->tx_data_rd);
|
||||
@ -1902,14 +1941,16 @@ static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, &tx_buffer[rfm22b_dev->tx_data_rd], NULL, bytes_to_write, NULL);
|
||||
rfm22b_dev->tx_data_rd += bytes_to_write;
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
// enable TX interrupts
|
||||
// Enable TX interrupts.
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, RFM22_ie1_enpksent | RFM22_ie1_entxffaem);
|
||||
|
||||
// enable the transmitter
|
||||
// Enable the transmitter.
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon | RFM22_opfc1_txon);
|
||||
|
||||
// Release the SPI bus.
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
TX_LED_ON;
|
||||
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
@ -2720,7 +2761,7 @@ static void rfm22_releaseBus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
* @param[in] addr The address to write to
|
||||
* @param[in] data The datat to write to that address
|
||||
*/
|
||||
static void rfm22_write(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data)
|
||||
static void rfm22_write_claim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data)
|
||||
{
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
@ -2731,22 +2772,18 @@ static void rfm22_write(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a byte from an RFM22b register
|
||||
* Write a byte to a register without claiming the semaphore
|
||||
*
|
||||
* @param[in] rfm22b_dev The RFM22B device structure pointer.
|
||||
* @param[in] addr The address to read from
|
||||
* @return Returns the result of the register read
|
||||
* @param[in] rfm22b_dev The RFM22B device.
|
||||
* @param[in] addr The address to write to
|
||||
* @param[in] data The datat to write to that address
|
||||
*/
|
||||
static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
static void rfm22_write(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data)
|
||||
{
|
||||
uint8_t in[2];
|
||||
uint8_t out[2] = {addr & 0x7f, 0xFF};
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, out, in, sizeof(out), NULL);
|
||||
uint8_t buf[2] = {addr | 0x80, data};
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, buf, NULL, sizeof(buf), NULL);
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
return in[1];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2756,7 +2793,7 @@ static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
* @param[in] addr The address to read from
|
||||
* @return Returns the result of the register read
|
||||
*/
|
||||
static uint8_t rfm22_read_noclaim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
{
|
||||
uint8_t out[2] = {addr & 0x7F, 0xFF};
|
||||
uint8_t in[2];
|
||||
|
@ -717,7 +717,7 @@ struct pios_rfm22b_dev {
|
||||
uint32_t tx_out_context;
|
||||
|
||||
// the transmit power to use for data transmissions
|
||||
uint8_t tx_power;
|
||||
uint8_t tx_power;
|
||||
|
||||
// The RF datarate lookup index.
|
||||
uint8_t datarate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user