/* * cc1200.c * * Created on: Feb 5, 2022 * Author: curiousmuch */ /* * Project: Arrow * Author: curiousmuch */ #include #include #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 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