123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*
- * cc1200.c
- *
- * Created on: Feb 5, 2022
- * Author: curiousmuch
- */
- /*
- * Project: Arrow
- * Author: curiousmuch
- */
- #include <stdio.h>
- #include <math.h>
- #include "main.h"
- #include "cc1200.h"
- #include "cc1200_protocol.h"
- #define BIT(n) (0x1U << (n))
- /* SPI Constants */
- #define CC1200_WRITE_BIT 0b00000000
- #define CC1200_READ_BIT 0b10000000
- #define CC1200_BURST_BIT 0b01000000
- void SPI1_TransmitBytes(uint8_t *p_buf, uint8_t len)
- {
- LL_SPI_SetTransferSize(SPI1, len);
- LL_SPI_Enable(SPI1);
- LL_SPI_StartMasterTransfer(SPI1);
- switch(len)
- {
- case 1:
- LL_SPI_TransmitData8(SPI1, *p_buf);
- break;
- case 2:
- LL_SPI_TransmitData16(SPI1, *(uint16_t *)p_buf);
- break;
- case 3:
- LL_SPI_TransmitData32(SPI1, *(uint32_t *)p_buf);
- break;
- default:
- assert(0);
- }
- // Wait until the transmission is complete
- while( LL_SPI_IsActiveFlag_EOT(SPI1) == 0);
- SPI1->IFCR = UINT32_MAX;
- LL_SPI_Disable(SPI1);
- }
- uint8_t SPI1_ReceiveByte(void)
- {
- uint8_t rxByte;
- LL_SPI_SetTransferSize(SPI1, 1);
- LL_SPI_Enable(SPI1);
- LL_SPI_StartMasterTransfer(SPI1);
- LL_SPI_TransmitData8(SPI1, 0);
- while (LL_SPI_IsActiveFlag_RXP(SPI1) == 0);
- rxByte = LL_SPI_ReceiveData8(SPI1);
- // Wait until the transmission is complete
- while( LL_SPI_IsActiveFlag_EOT(SPI1) == 0);
- SPI1->IFCR = UINT32_MAX;
- LL_SPI_Disable(SPI1);
- return rxByte;
- }
- uint8_t SPI1_TransmitReceive(uint8_t *p_buf, uint8_t len)
- {
- SPI1_TransmitBytes(p_buf, len);
- return SPI1_ReceiveByte();
- }
- // TODO: Fix to use HAL.
- static void cc1200_spi_write_byte(uint16_t addr, uint8_t data)
- {
- uint8_t txBuf[3];
- // set the data field
- HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 0);
- if ((addr & 0xFF00) != 0) // send data with extended address in command field
- {
- txBuf[0] = ((uint8_t *)&addr)[1];
- txBuf[1] = ((uint8_t *)&addr)[0];
- txBuf[0] |= CC1200_WRITE_BIT;
- txBuf[2] = data;
- SPI1_TransmitBytes(txBuf, 3);
- }
- else
- {
- // correctly configure the addr field.
- txBuf[0] = (uint8_t)addr | CC1200_WRITE_BIT;
- txBuf[1] = data;
- SPI1_TransmitBytes(txBuf, 2);
- }
- HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 1);
- }
- //static void cc1200_spi_write_bytes(uint16_t addr, uint8_t* data, uint8_t len)
- //{
- // esp_err_t ret;
- // spi_transaction_t tx_trans =
- // {
- // .cmd = (CC1200_WRITE_BIT | CC1200_BURST_BIT),
- // .addr = addr,
- // .length = 8*len,
- // .tx_buffer = data
- // };
- // if ((addr & 0xFF00) != 0) // send data with extended address in command field
- // {
- // tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
- // spi_transaction_ext_t tx_trans_ext =
- // {
- // .base = tx_trans,
- // .command_bits = 2,
- // .address_bits = 14
- // };
- // ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
- // }
- // else
- // {
- // ret = spi_device_polling_transmit(spi, &tx_trans);
- // }
- // ESP_ERROR_CHECK(ret);
- //}
- // TODO: Fix to use HAL.
- static void cc1200_spi_read_byte(uint16_t addr, uint8_t* data)
- {
- uint8_t rxBuf[3];
- uint8_t txBuf[3];
- // correctly configure the addr field.
- txBuf[0] = (uint8_t)addr | CC1200_READ_BIT;
- HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 0);
- if ((addr & 0xFF00) != 0) // read data with extended address in command field
- {
- txBuf[0] = ((uint8_t *)&addr)[1];
- txBuf[1] = ((uint8_t *)&addr)[0];
- txBuf[0] |= CC1200_READ_BIT;
- *data = SPI1_TransmitReceive(txBuf, 2);
- }
- else
- {
- *data = SPI1_TransmitReceive(txBuf, 1);
- }
- HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 1);
- }
- //static void cc1200_spi_read_bytes(uint16_t addr, uint8_t* data, uint8_t len)
- //{
- // esp_err_t ret;
- // spi_transaction_t rx_trans =
- // {
- // .cmd = (CC1200_READ_BIT | CC1200_BURST_BIT),
- // .addr = addr,
- // .length = 8*len,
- // .rxlength = 8*len,
- // .rx_buffer = data
- // };
- // if ((addr & 0xFF00) != 0) // read data with extended address in command field
- // {
- // rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
- // spi_transaction_ext_t rx_trans_ext =
- // {
- // .base = rx_trans,
- // .command_bits = 2,
- // .address_bits = 14
- // };
- // ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
- // }
- // else
- // {
- // ret = spi_device_polling_transmit(spi, &rx_trans);
- // }
- // ESP_ERROR_CHECK(ret);
- //}
- // TODO: Fix to use HAL.
- rf_status_t cc1200_spi_strobe(uint8_t cmd)
- {
- uint8_t txBuf[2];
- txBuf[0] = cmd;
- HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 0);
- uint8_t rxByte;
- LL_SPI_SetTransferSize(SPI1, 1);
- LL_SPI_Enable(SPI1);
- LL_SPI_StartMasterTransfer(SPI1);
- LL_SPI_TransmitData8(SPI1, cmd);
- while (LL_SPI_IsActiveFlag_RXP(SPI1) == 0);
- rxByte = LL_SPI_ReceiveData8(SPI1);
- // Wait until the transmission is complete
- while( LL_SPI_IsActiveFlag_EOT(SPI1) == 0);
- SPI1->IFCR = UINT32_MAX;
- LL_SPI_Disable(SPI1);
- HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 1);
- return rxByte & 0xF0;
- }
- // writes array or register value pairs from smart RF studio to CC1200
- // w/o reseting
- void cc1200_radio_config(const cc1200_reg_settings_t* rf_settings, uint8_t len)
- {
- uint8_t i;
- for (i=0;i<len;i++)
- {
- cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
- }
- }
- /* CC1200 Driver Public Functions */
- uint8_t cc1200_radio_read_RSSI(void)
- {
- uint8_t data = 0;
- cc1200_spi_read_byte(CC120X_RSSI1, &data);
- return data;
- }
- uint8_t cc1200_radio_read_CFM(void)
- {
- uint8_t data = 0;
- cc1200_spi_read_byte(CC120X_CFM_RX_DATA_OUT, &data);
- return data;
- }
- void cc1200_radio_write_CFM(int8_t data)
- {
- cc1200_spi_write_byte(CC120X_CFM_TX_DATA_IN, data);
- }
- rf_status_t cc1200_radio_reset(void)
- {
- rf_status_t status;
- uint8_t retry_count = 0;
- cc1200_spi_strobe(CC120X_SRES); // soft reset the chip
- status = cc1200_spi_strobe(CC120X_SNOP); // get chip status
- HAL_Delay(20);
- while((CC120X_RDYn_BIT & (status & 0x80))) // if chip isn't ready, wait 10ms
- {
- HAL_Delay(10);
- if (retry_count > 3)
- {
- break;
- }
- status = cc1200_spi_strobe(CC120X_SNOP);
- retry_count++;
- }
- return status;
- }
- #define CC1200_LO_DIVIDER 24 // 136.7 - 160 MHz Band
- #define CC1200_XOSC 40000000 // 40MHz
- void cc1200_radio_frequency(uint32_t freq)
- {
- // f_RF = f_VCO / LO Divider
- // f_VCO = FREQ / 2^16 * f_XOSX + FREQOFF / 2^18 * F_XOSC
- double temp_freq;
- // calculate FREQ0, FREQ, FREQ2 registers
- temp_freq = ((double) freq * 65536 * CC1200_LO_DIVIDER) / CC1200_XOSC;
- freq = (uint32_t)temp_freq;
- cc1200_spi_write_byte(CC120X_FREQ0, ((uint8_t *)&freq)[0]);
- cc1200_spi_write_byte(CC120X_FREQ1, ((uint8_t *)&freq)[1]);
- cc1200_spi_write_byte(CC120X_FREQ2, ((uint8_t *)&freq)[2]);
- return ;
- }
- void cc1200_radio_sleep(void)
- {
- // TODO: Write CC1200 sleep function
- return;
- }
- void cc1200_radio_power(uint8_t txPower)
- {
- // TODO: Write function to set CC1200 power
- return;
- }
- void cc1200_radio_idle(void)
- {
- // TODO: Create exception for failure condition
- while (cc1200_spi_strobe(CC120X_SIDLE) != CC120X_STATE_IDLE);
- }
- void cc1200_radio_tx(void)
- {
- // TODO: Create exception for failure condition
- while (cc1200_spi_strobe(CC120X_STX) != CC120X_STATE_TX);
- }
- void cc1200_radio_rx(void)
- {
- // TODO: Create exception for failure condition
- while (cc1200_spi_strobe(CC120X_SRX) != CC120X_STATE_RX);
- }
- // TODO: Fix to use HAL.
- void cc1200_radio_init(const cc1200_reg_settings_t* rf_settings, uint8_t len)
- {
- //cc1200_gpio_init();
- //cc1200_spi_init();
- cc1200_radio_reset(); //gpio_set_level(CC1200_RESET, 1);
- uint8_t i;
- for (i=0;i<len;i++)
- {
- cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
- }
- while(cc1200_spi_strobe(CC120X_SIDLE) != CC120X_STATE_IDLE);
- }
|