Part Number: MSP430F5438A
Other Parts Discussed in Thread: CC1200,
Hello World!
So I'm using sniff example code from the TI website to send data through the RF system. I modified it a little bit, so that it is possible to send data, obtained by a pulsed output. It’s working very well.
I am using two MSP430F5438a modules with the CC1200. The first one works as the remote unit to collect information from the pulsed output and the second one is local unit to receive.
But I’m not able to do the communication of the second module with the PC to verify all receive data on a remote terminal, what I mean is, I need to send data between two points and see the data in a terminal.
I’ve problems with UART communication.
I used bspUartOpen function to defined baud rate, bspUartDataPut to put data in Uart to prepare to send but what I need to do now? Use some instruction like printf? I've tried but didn't work.
I am working with the IAR and if anybody can help me, the code follows below.
Thanks!
//******************************************************************************
//! @file cc1200_rx_sniff_mode_rx.c
//! @brief This program demonstrates Rx Sniff Mode for the 38.4 kbps
// setting available in SmartRf Studio.
// The transmitter sends a packet every time a button is pushed and
// the receiver implements RX Sniff Mode to reduce the current
// consumption.
// DN511 (http://www.ti.com/lit/swra428) explains how the register
// settings are found.
//
// Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//*****************************************************************************/
/*******************************************************************************
* INCLUDES
*/
#include "msp430.h"
#include "lcd_dogm128_6.h"
#include "hal_spi_rf_trxeb.h"
#include "cc120x_spi.h"
#include "stdlib.h"
#include "bsp.h"
//#include "bsp_key.h"
#include "io_pin_int.h"
#include "bsp_led.h"
#include "projeto_vazao_reg_config.h"
#include "stdio.h"
#include "string.h"
#include "bsp_uart.h"
/*******************************************************************************
* DEFINES
*/
#define ISR_ACTION_REQUIRED 1
#define ISR_IDLE 0
#define PKTLEN 30 // 1 < PKTLEN < 126
#define GPIO3 0x04
#define GPIO2 0x08
#define GPIO0 0x80
/*******************************************************************************
* LOCAL VARIABLES
*/
static uint8 packetSemaphoreTX, packetSemaphoreRX;
static uint32 packetCounter = 0, x;
unsigned char dadox[200];
uint16 dado = 0;
/*******************************************************************************
* STATIC FUNCTIONS
*/
static void initMCU(void);
static void registerConfig(void);
static void runRX(void);
static void radioRxISR(void);
static void updateLcd(uint16 dado1, uint16 dado2);
static void calibrateRCOsc(void);
static void initRX(void);
static void initTX(void);
static void runTX(void);
static void radioTxISR(void);
static void createPacket(uint8 txBuffer[], uint16 dado);
uint16 enviado = 0, recebido = 0;
#define set_bit(y,bit) (y|=(1<<bit)) // set bit x from byte Y
#define clr_bit(y,bit) (y&=~(1<<bit)) // clear bit x from byte Y
#define cpl_bit(y,bit) (y^=(1<<bit)) // toggle bit x from byte Y
#define tst_bit(y,bit) (y&(1<<bit)) // test bit
void init()
{
// Initialize MCU and peripherals
initMCU();
// Write radio registers
registerConfig();
//initTX();
//initRX();
updateLcd(enviado, recebido);
}
/****************************************************************************
* uint16_t
* bspUartDataPut(uint8_t *pui8Data, uint16_t ui16Length)
*
* @brief This function puts up to \e ui16Length bytes into the BSP UART TX
* buffer and starts to transfer data over UART.
*
* If \b BSP_UART_ALL_OR_NOTHING is defined, data is put into the
* TX buffer only if there is room for all \e ui16Length bytes.
*
* @param pui8Data is a pointer to the source buffer.
* @param ui16Length is the number of bytes to transfer.
*
* @return Returns the number of bytes actually copied to the TX buffer.
******************************************************************************/
/*******************************************************************************
* @fn main
*
* @brief Runs the main routine
*
* @param none
*
* @return none
*/
void main(void) {
init();
// Enter runRX, never coming back
initRX();
while(1)
{
//runRX();
updateLcd(enviado, recebido);
if(packetSemaphoreRX == ISR_ACTION_REQUIRED)
{
for(x = 0; x < 1000; x++);
initTX();
runTX();
initRX();
updateLcd(enviado, recebido);
/******************************************************************************************
******************* Communication test with remote terminal *************************
*/
bspUartOpen(BSP_UART_BR_115200);
bspUartDataPut((uint8_t *)recebido, 1);
/*
*************************** end test *****************************************
*******************************************************************************/
// Clear semaphore flag
packetSemaphoreRX = ISR_IDLE;
}
}
}
/*******************************************************************************
* @fn initTX
*
* @brief Configura o modo TX para enviar dados.
*
* @param none
*
* @return none
*/
static void initTX(void)
{
static uint8 marcState;
// Connect ISR function to GPIO0
ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &radioTxISR);
// Interrupt on falling edge
ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_FALLING_EDGE);
// Clear ISR flag
ioPinIntClear(IO_PIN_PORT_1, GPIO0);
// Enable interrupt
ioPinIntEnable(IO_PIN_PORT_1, GPIO0);
// Update LCD
//updateLcd();
// Calibrate radio
trxSpiCmdStrobe(CC120X_SCAL);
// Wait for calibration to be done (radio back in IDLE state)
do {
cc120xSpiReadReg(CC120X_MARCSTATE, &marcState, 1);
} while (marcState != 0x41);
}
/*******************************************************************************
* @fn runTX
*
* @brief Transmits a packet.
*
* @param none
*
* @return none
*/
static void runTX(void) {
// Initialize packet buffer of size PKTLEN + 1
uint8 txBuffer[PKTLEN + 1];
// Infinite loop
//while(TRUE) {
// Wait for button push
//while(!bspKeyPushed(BSP_KEY_ALL));
// Create a random packet with PKTLEN + 2 byte packet counter + n x random bytes
enviado++;
createPacket(txBuffer, enviado);
// Write packet to TX FIFO
cc120xSpiWriteTxFifo(txBuffer, sizeof(txBuffer));
// Strobe TX to send packet
trxSpiCmdStrobe(CC120X_STX);
// Wait for packet to be sent
while(packetSemaphoreTX != ISR_ACTION_REQUIRED);
// Clear semaphore flag
packetSemaphoreTX = ISR_IDLE;
// Update LCD
//updateLcd();
//}
}
/*******************************************************************************
* @fn radioTxISR
*
* @brief ISR for packet handling in TX. Sets packet semaphore
* and clears interrupt flag
*
* @param none
*
* @return none
*/
static void radioTxISR(void) {
// Set packet semaphore
packetSemaphoreTX = ISR_ACTION_REQUIRED;
cpl_bit(P4OUT,2); // Alterna bit
// Clear ISR flag
ioPinIntClear(IO_PIN_PORT_1, GPIO0);
}
/*******************************************************************************
* @fn createPacket
*
* @brief This function is called before a packet is transmitted. It fills
* the txBuffer with a packet consisting of a length byte, two
* bytes packet counter and n random bytes
*
* The packet format is as follows:
* |--------------------------------------------------------------|
* | | | | | | |
* | pktLength | pktCount1 | pktCount0 | rndData |.......| rndData|
* | | | | | | |
* |--------------------------------------------------------------|
* txBuffer[0] txBuffer[1] txBuffer[2] ......... txBuffer[PKTLEN]
*
* @param Pointer to start of txBuffer
*
* @return none
*/
static void createPacket(uint8 txBuffer[], uint16 dado) {
txBuffer[0] = PKTLEN; // Length byte
txBuffer[1] = (uint8) (packetCounter >> 8); // MSB of packetCounter
txBuffer[2] = (uint8) packetCounter; // LSB of packetCounter
txBuffer[3] = (uint8) (dado >> 8);
txBuffer[4] = (uint8) dado;
for(uint8 i = 5; i < (PKTLEN + 1); i++) txBuffer[i] = 0;
// Fill rest of buffer with random bytes
//for(uint8 i = 3; i < (PKTLEN + 1); i++) {
// txBuffer[i] = (uint8)rand();
//}
}
/*******************************************************************************
* @fn initRX
*
* @brief Puts radio in RX Sniff Mode and waits for packets.
*
* @param none
*
* @return none
*/
static void initRX(void)
{
uint8 marcState;
// Connect ISR function to GPIO2
ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &radioRxISR);
// Interrupt on falling edge
ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_RISING_EDGE);
// Clear ISR flag
ioPinIntClear(IO_PIN_PORT_1, GPIO2);
// Enable interrupt
ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
// Update LCD
updateLcd(enviado, recebido);
// Calibrate radio
trxSpiCmdStrobe(CC120X_SCAL);
// Wait for calibration to be done (radio back in IDLE state)
do {
cc120xSpiReadReg(CC120X_MARCSTATE, &marcState, 1);
} while (marcState != 0x41);
// Calibrate the RCOSC
calibrateRCOsc();
// Set radio in RX Sniff Mode
trxSpiCmdStrobe(CC120X_SWOR);
}
/*******************************************************************************
* @fn runRX
*
* @brief Puts radio in RX Sniff Mode and waits for packets. A packet
* counter is incremented for each packet received and the LCD is
* updated
*
* @param none
*
* @return none
*/
static void runRX(void) {
uint8 rxBuffer[128] = {0};
uint8 rxBytes;
// Infinite loop
//while(TRUE) {
// Set radio in RX Sniff Mode
//trxSpiCmdStrobe(CC120X_SWOR);
// Wait for packet to be received
while(packetSemaphoreRX != ISR_ACTION_REQUIRED);
// Clear semaphore flag
//packetSemaphoreRX = ISR_IDLE;
// Read number of bytes in RX FIFO
cc120xSpiReadReg(CC120X_NUM_RXBYTES, &rxBytes, 1);
// Read all the bytes in the RX FIFO
cc120xSpiReadRxFifo(rxBuffer, rxBytes);
recebido = (rxBuffer[3]<<8) + rxBuffer[4];
// Update LCD
updateLcd(enviado, recebido);
// cpl_bit(P4OUT,0); // Alterna bit
//}
}
/*******************************************************************************
* @fn calibrateRcOsc
*
* @brief Calibrates the RC oscillator used for the eWOR timer. When this
* function is called, WOR_CFG0.RC_PD must be 0
*
* @param none
*
* @return none
*/
static void calibrateRCOsc(void) {
uint8 temp;
// Read current register value
cc120xSpiReadReg(CC120X_WOR_CFG0, &temp,1);
// Mask register bit fields and write new values
temp = (temp & 0xF9) | (0x02 << 1);
// Write new register value
cc120xSpiWriteReg(CC120X_WOR_CFG0, &temp,1);
// Strobe IDLE to calibrate the RCOSC
trxSpiCmdStrobe(CC120X_SIDLE);
// Disable RC calibration
temp = (temp & 0xF9) | (0x00 << 1);
cc120xSpiWriteReg(CC120X_WOR_CFG0, &temp, 1);
}
/*******************************************************************************
* @fn radioRxISR
*
* @brief ISR for packet handling in RX. Sets packet semaphore
* and clears interrupt flag
*
* @param none
*
* @return none
*/
static void radioRxISR(void) {
// Set packet semaphore
packetSemaphoreRX = ISR_ACTION_REQUIRED;
runRX();
// Clear ISR flag
ioPinIntClear(IO_PIN_PORT_1, GPIO2);
}
/*******************************************************************************
* @fn initMCU
*
* @brief Initialize MCU and board peripherals
*
* @param none
*
* @return none
*/
static void initMCU(void) {
// Init clocks and I/O
bspInit(BSP_SYS_CLK_8MHZ);
// Init LEDs
bspLedInit();
// Init buttons
//bspKeyInit(BSP_KEY_MODE_POLL);
// Initialize SPI interface to LCD (shared with SPI flash)
bspIoSpiInit(BSP_FLASH_LCD_SPI, BSP_FLASH_LCD_SPI_SPD);
// Init LCD
lcdInit();
// Instantiate transceiver RF SPI interface to SCLK ~ 4 MHz
// Input parameter is clockDivider
// SCLK frequency = SMCLK/clockDivider
trxRfSpiInterfaceInit(2);
// Enable global interrupt
_BIS_SR(GIE);
}
/*******************************************************************************
* @fn registerConfig
*
* @brief Write register settings as given by SmartRF Studio found in
* cc1200_rx_sniff_mode_reg_config.h
*
* @param none
*
* @return none
*/
static void registerConfig(void) {
uint8 writeByte;
// Reset radio
trxSpiCmdStrobe(CC120X_SRES);
// Write registers to radio
for(uint16 i = 0;
i < (sizeof(preferredSettings)/sizeof(registerSetting_t)); i++) {
writeByte = preferredSettings[i].data;
cc120xSpiWriteReg(preferredSettings[i].addr, &writeByte, 1);
}
}
/*******************************************************************************
* @fn updateLcd
*
* @brief Updates LCD buffer and sends buffer to LCD module
*
* @param none
*
* @return none
*/
static void updateLcd(uint16 dado1, uint16 dado2) {
// Update LDC buffer and send to screen
lcdBufferClear(0);
lcdBufferPrintString(0, "Concentrador", 0, eLcdPage0);
lcdBufferSetHLine(0, 0, LCD_COLS - 1, 7);
lcdBufferPrintString(0, "Recebido:", 0, eLcdPage3);
lcdBufferPrintInt(0, dado2, 80, eLcdPage3);
lcdBufferPrintString(0, "Enviado:", 0, eLcdPage4);
lcdBufferPrintInt(0, dado1, 80, eLcdPage4);
//lcdBufferPrintInt(0, packetCounter++, 70, eLcdPage4);
lcdBufferPrintString(0, "RX", 0, eLcdPage7);
lcdBufferSetHLine(0, 0, LCD_COLS - 1, 55);
lcdBufferInvertPage(0, 0, LCD_COLS, eLcdPage7);
lcdSendBuffer(0);
}