I want to use RTS pin of UART1 to communicate through RS 485 protocol.
I have enabled UART1 through
/media/BEAGLEBONE/uEnv.txt
optargs=quiet drm.debug=7 capemgr.enable_partno=BB-UART1
Device tree overlay snippet:
0x180 0x20 /* uart1_rxd | MODE0 */
0x184 0x20 /* uart1_txd | MODE0 */
0x17c 0x00 /* uart1_rts | MODE0 */
0x178 0x00 /* uart1_cts | MODE0 */
cat /proc/tty/driver/OMAP-SERIAL
serinfo:1.0 driver revision:
0: uart:OMAP UART0 mmio:0x44E09000 irq:72 tx:2818 rx:100 RTS|CTS|DTR|DSR
1: uart:OMAP UART1 mmio:0x48022000 irq:73 tx:0 rx:0 CTS|DSR|CD|RI
How to enable RTS pin on P9.19 by selecting mode 0 ?
The muxing mode of the pins both set to same mode.
Change it to:
0x180 0x20 /* UART1_RXD, INPUT | MODE0 */
0x184 0x00 /* UART1_TXD, OUTPUT | MODE0 */
0x17c 0x00 /*UART1_RTS*/
0x178 0x20 /*UART1_CTS*/
To use the RTS pin send the pin number from the overlay.
rts-gpio = <&gpio0 13 0>
Related
I have a problem with my system and I can't handle the problem. Problem is that ;
When I powered the system with DC volt (3.3 v) without debugging then I can't see anything on the receiver side (Arduino Uno as receiver). However if I use debugger[FET430 - UIF ] then I can see all of the characters on the receiver side.
This is my code :
#include <msp430.h>
#include "cc430x613x.h"
#include <msp430.h>
#include <string.h>
void terminal_write();
void UART_open();
void UART_close();
void main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
//__delay_cycles( 2 * 1e7);
while(1)
{
UART_open();
printf("system working\r\n");
terminal_write("AT\r\n");
__delay_cycles(5000000);
//_bis_SR_register(LPM3_bits + GIE);
UART_close();
}
}
void terminal_write(char *info)
{
unsigned int i;
unsigned int len = strlen(info) ;
for(i=0;i<len;i++)
{
UCA0TXBUF=info[i];
__delay_cycles(10000);
}
}
void UART_open(){
P1SEL |= BIT5 + BIT6;
//UART Settings
UCA0CTL1 |= UCSWRST;
UCA0CTL1 |= UCSSEL0 ; // ACLK
UCA0BR0=3; //UCA0BR0 = 3 ; //32Khz / 9600 –>> 3
UCA0BR1=0; //UCA0BR1=0; // BAUD 9600; ( UCABR1 * 256 ) + UCABR0 = UCABRx see "slau259e.pdf"
UCA0MCTL=6 ; // see "slau259e.pdf" page 602 //
//UCA0MCTL =| BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0 |
// |------- UCBRFx --------------|----UCBRSx----------|UCOS16|
// for 9600 baudrate at 32kHz UCBRFx = 0 , UCBRSx = 3 , UCOS16 = 0
// | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
// 0b00000110 = 0x06 = 6
UCA0CTL1 &=~ UCSWRST;//
UCA0CTL1 |= UCDORM;
}
void UART_close(){
P1SEL &= ~(BIT5 + BIT6);
UCA0CTL1 |= UCSWRST;
UCA0CTL1 &=~ UCDORM;
}
Beside if I use DC power then the system consumption is about 450-550 uA. If I use debugger then the DC power consumption is raises to about 4.8 mA . Also if I only use the debugger [powered with debugger voltage without using any external DC supply] then system can't handle the communication properly.
If there is a solutiion I'll very appreciate.
Firtina, is it possible that you are only connecting the DC power supply to the analog voltage input (AVSS) and not the digital input (DVCC)? If so, then my explanation is the JTAG tool is supplying the CCF6137 chip with proper power, but when disconnected the chip doesn't have power to the digital side. If this is the case, then try connecting the DC power supply to both AVSS and DVCC pins and test again without the JTAG tool. Also, check that you are giving the chip proper ground.
I know the default setting value for 'VIRTUAL_COM_PORT_DATA_SIZE 64' at usb_desc.h for STM32 Library.
however, I want to get the 255 bytes at one time due to the long packets of our project.
So I have changed the following modify code point, I couldn't get the right value with problem for 'USB defect problem'.
/****** usb_prop.c **********/
DEVICE_PROP Device_Property = {
Virtual_Com_Port_init,
Virtual_Com_Port_Reset,
Virtual_Com_Port_Status_In,
Virtual_Com_Port_Status_Out,
Virtual_Com_Port_Data_Setup,
Virtual_Com_Port_NoData_Setup,
Virtual_Com_Port_Get_Interface_Setting,
Virtual_Com_Port_GetDeviceDescriptor,
Virtual_Com_Port_GetConfigDescriptor,
Virtual_Com_Port_GetStringDescriptor,
0,
0xFF /*MAX PACKET SIZE*/ // default : 0x40
};
/****** usb_desc.c **********/
/* USB Standard Device Descriptor */
const uint8_t Virtual_Com_Port_DeviceDescriptor[] = {
0x12, /* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x00,
0x02, /* bcdUSB = 2.00 */
0x02, /* bDeviceClass: CDC */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0xFF, /* bMaxPacketSize0 */ // default : 0x40
0x83,
0x04, /* idVendor = 0x0483 */
0x40,
0x57, /* idProduct = 0x7540 */
0x00,
0x02, /* bcdDevice = 2.00 */
1, /* Index of string descriptor describing manufacturer */
2, /* Index of string descriptor describing product */
3, /* Index of string descriptor describing the device's serial number */
0x01 /* bNumConfigurations */ };
/****** usb_desc.h **********/
#define VIRTUAL_COM_PORT_DATA_SIZE 255 // 0xFF, default : 64
please tell me how to modify in order to send as 255 bytes from USB packets.
You can't do it this way. The size of the packet is USB endpoint related and for the FS USB it is always 64 bytes. My advice is: do not modify any descriptors unless you really know what are you doing (which is not the case here).
How to receive larger chunks of data:
create a buffer
when data arrives copy it (append) to that buffer
check if you have received all data needed
if not go to point (2) else goto point(5)
Do something with the data (your large packet)
Reset the buffer and goto point 2
I'm trying to achieve 10MSPS as documented in STM32F30x ADC modes and application under the section Dual interleaved mode.
Firstly, i tried to use single DMA. I configured the DMA1 Channel1 to read from ADC1&2 Common data register. It worked but i could only achieve a sample rate of 8.47MSPS. Beyond that limit, ADC1 starts to overrun.
(Register ADC1_2->CCR: MULT=0x07, MDMA=0x02, DELAY=0x04) Considering the DMA reading the common data register after the slave adc ends its conversion, the problem seems reasonable at high sample rates.
So i decided to use 2 DMAs. One for each ADC:
DMA1 Channel1 copies from ADC1->DR to SRAM
DMA2 Channel1 copies from ADC2->DR to SRAM
(Register ADC1_2->CCR: MULT=0x07, MDMA=0x00, DELAY=0x04)
This configuration also worked but again up to 8MSPS. Above that rate, ADC2 starts to overrun. I cannot understand why ADC2 overruns. I expected that this setup would work.
When i run ADC1 & ADC2 in independent mode with DMA configuration above, everything seems to work fine. No overruns, both ADC samples at 5.1MSPS but independently.
One question: What happens when both ADCs run in independent mode and triggered from the same source (e.g. TIM2) but ADC1 is triggered at the rising edge and ADC2 is triggered at the falling edge of the clock ? Would it work? This is the next thing i will try.
The MCU i work with is STM32F303CB.
ADC sampling times were 1.5 Cycles.
Any advice will be appreciated.
Edit: I have provided a minimal sample code that runs on STM32F3 Discovery with an 8 MHz Crystal. Program directly jumps to main()
// main.c
#include "stm32f30x.h"
#define DUALDMA
void sysinit();
void clockconfig();
void delay(int d);
void timerinit();
void adcinit();
void dmainit();
void dualdmainit();
int main(){
sysinit();
clockconfig();
timerinit();
#ifdef DUALDMA
dualdmainit();
#else
dmainit();
#endif
adcinit();
RCC->AHBENR |= RCC_AHBENR_GPIOEEN; // GPIOE enable
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // GPIOA enable
GPIOE->MODER = 0x55555555; // GPIOE -> output
GPIOA->MODER |= 0x0000FFFF;// GPIOA -> analog
// Reset SRAM memory area
for(int i = 0;i<1024*4;i+=4){
*((uint32_t*)(0x20000800+i)) = 0;
}
// Blink LEDs
while(1){
GPIOE->ODR = 0xFFFF;
delay(1000);
GPIOE->ODR = 0x00FF;
delay(1000);
}
}
void delay(int d){
// Dummy delay
int l = d*1000;
for(int i = 0;i<l;i++);
}
void sysinit(){
//STM32F303 reset state
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= 0x00000001U;
/* Reset CFGR register */
RCC->CFGR &= 0xF87FC00CU;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= 0xFEF6FFFFU;
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
RCC->CFGR &= 0xFF80FFFFU;
/* Reset PREDIV1[3:0] bits */
RCC->CFGR2 &= 0xFFFFFFF0U;
/* Reset USARTSW[1:0], I2CSW and TIMs bits */
RCC->CFGR3 &= 0xFF00FCCCU;
/* Disable all interrupts */
RCC->CIR = 0x00000000U;
SCB->VTOR = 0x08000000; /* Vector Table Relocation in Internal FLASH */
}
void adcinit(){
RCC->AHBENR |= RCC_AHBENR_ADC12EN; // Enable ADC clock
RCC->CFGR2 |= RCC_CFGR2_ADCPRE12_4;// ADC clock prescaler = 1
ADC1->CFGR |= ADC_CFGR_EXTEN_0; // Trigger on rising edge
ADC1->CFGR |= ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1; // TIM1 TRGO2
ADC1->SQR1 |= ADC_SQR1_SQ1_0 ; // ch 1
ADC1->CFGR |= ADC_CFGR_OVRMOD; // Stop on overrun
ADC1->CFGR |= ADC_CFGR_DMAEN; // DMA enable
ADC1->CR &= ~(ADC_CR_ADVREGEN_1 | ADC_CR_ADVREGEN_0); // Enable VREG
ADC1->CR |= ADC_CR_ADVREGEN_0;
ADC1->CR |= ADC_CR_ADEN;
while( (ADC1->ISR & ADC_ISR_ADRD) == 0 );
ADC2->SQR1 |= ADC_SQR1_SQ1_0 ; // ch 1
ADC2->CFGR |= ADC_CFGR_DMAEN;
ADC2->CR &= ~(ADC_CR_ADVREGEN_1 | ADC_CR_ADVREGEN_0);
ADC2->CR |= ADC_CR_ADVREGEN_0;
ADC2->CR |= ADC_CR_ADEN;
while( (ADC1->ISR & ADC_ISR_ADRD) == 0 );
ADC1_2->CCR |= ADC12_CCR_DELAY_2 ; // Delay = 4, 5 Cycles
#ifndef DUALDMA
ADC1_2->CCR |= ADC12_CCR_MDMA_1; // If single DMA is selected, configure MDMA bits for 12 bits
#endif
ADC1_2->CCR |= ADC12_CCR_MULTI_2 | ADC12_CCR_MULTI_1 | ADC12_CCR_MULTI_0; // Interleaved mode
}
void dmainit(){
// DMA config for Single DMA, 32 bits
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel1->CPAR = (uint32_t)&ADC1_2->CDR;
DMA1_Channel1->CMAR = 0x20000800;
DMA1_Channel1->CNDTR = 1024;
DMA1_Channel1->CCR = DMA_CCR_EN | DMA_CCR_MINC | DMA_CCR_MSIZE_1 | DMA_CCR_PSIZE_1;
//DMA1_Channel1->CCR = DMA_CCR_EN | DMA_CCR_MINC ;
}
void dualdmainit(){
// DMA config for DUAL DMA, 16bits
RCC->AHBENR |= RCC_AHBENR_DMA1EN; // DMA1 Enable
RCC->AHBENR |= RCC_AHBENR_DMA2EN; // DMA2 Enable
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
DMA1_Channel1->CMAR = 0x20000800;
DMA1_Channel1->CNDTR = 1024;
DMA1_Channel1->CCR = DMA_CCR_EN | DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0;
DMA2_Channel1->CPAR = (uint32_t)&ADC2->DR;
DMA2_Channel1->CMAR = 0x20000800+1024*2;
DMA2_Channel1->CNDTR = 1024;
DMA2_Channel1->CCR = DMA_CCR_EN | DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0;
}
void timerinit(){
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Enable TIM1
TIM1->CR2 |= TIM_CR2_MMS2_1; // Update event selected as TRGO2
TIM1->PSC = 0;
TIM1->ARR = 0x0d; // 5 MHz (72 MHz / 14 )
TIM1->CR1 |= TIM_CR1_CEN;
}
void clockconfig(){
// External oscillator (HSE): 8MHz
RCC->CR |= RCC_CR_HSEON; // Enable HSE
while( (RCC->CR & RCC_CR_HSERDY) == 0 );
RCC->CFGR |= RCC_CFGR_PLLMULL9; // PLL MUL = x9
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // APB1 Prescaler = 2
RCC->CFGR |= RCC_CFGR_PLLSRC; // PLL source = HSE
FLASH->ACR |= FLASH_ACR_LATENCY_1; // Two wait states
RCC->CR |= RCC_CR_PLLON; // Enable and wait PLL
while( (RCC->CR & RCC_CR_PLLRDY) == 0 );
RCC->CFGR |= RCC_CFGR_SW_PLL; // Select PLL as system clock
}
Scatter file:
LR_IROM1 0x08000000 0x00020000 { ; load region size_region
ER_IROM1 0x08000000 0x00020000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM2 0x10000000 0x00000200 { ; RW data
.ANY (+RW +ZI)
}
}
You cant do it this way. You need to use only one DMA channel and both samples are transmitted in one 32 bit DMA transaction.
In 6 bits mode I have archived more than 18MSPS
I do not know how to program it using HAL as I personally do only the bare register approach
There is a hardware problem as well (read the errata) and sometimes in >8bit modes the transfer does not work properly.
For dual DMA you need to:
Prevent any core accesses to the SRAM memory by placing the stack and the variables (except the ADC buffers) in the CCM RAM or suspending any core activity by entering the sleep mode.
I'm using the TFT display ILI9341 linked to the Adafruit HUZZAH through SPI with the example skecth provided "graphictest" and everythings works fine.
// HUZZAH DEVICE Spakfun nRf52
// Violet -- 12 --> MISO <-- 12 -- Violet
// Rouge -- 3V --> LED <-- 3V3-- Orange
// Vert -- 14 --> SCK <-- 13 -- Vert
// Bleu -- 13 --> MOSI <-- 11 -- Bleu
// Blanc #-- 4 --> D/C <-- 9 -- Marron
// Bleu -- 3V --> RESET <-- 3v3-- Gris
// Blanc o-- 5 --> CS <-- 10 -- Jaune
// Noir -- GND--> GND <-- GND-- Noir
// Rouge -- 3V --> VCC <-- 3V3-- Vcc
I want to do the same things with the SparkFun nRF52832 Breakout but the sketch stop during "tft.begin()"
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
void setup() {
Serial.begin(9600);
Serial.println("ILI9341 Test!");
tft.begin();
I also checked the header : variant.h
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (12)
#define PIN_SPI_MOSI (11)
#define PIN_SPI_SCK (13)
static const uint8_t SS = 10 ;
static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ;
I try to use SDcard slot built-in on the ILI9341 display, it's fine with HUZZAH but KO with Sparkfun nRf52.
If some of you could help me, it would be very kind.
Thanks.
The following is the interrupt handler for LED0 to toggle when an interrupt occurs on the UART0 due to LIN transmission from master to slave, my device is the slave. But without connecting my device(slave) to the master that means without any LIN transmission over UART, the LED0 is toggling. I cannot understand, how can this happen automatically? How can an interrupt be generated and Toggle of LED0 can happen?
void FTM0_IRQHandler()
{
if (1==((FTM0_C0SC & FTM_CnSC_CHF_MASK)>>FTM_CnSC_CHF_SHIFT) ) /* If the CHF of the channel is equal to 0 */
{
(void)FTM0_C0SC; /* Read to clear flag */
FTM0_C0SC ^= FTM_CnSC_CHF_MASK; /* Clear flag */
FTM0_C0V = FTM0_C0V + 391 ; /* Refresh interrupt period */
if (LED_counter>=50){
/* Toggle LED for LIN transmission */
/* Reset counter */
LED0_TOGGLE;
LED_counter = 0;
}
LED_counter++;
}
}
In my main funtion I have called my timer initialization as follows:
lin_application_timer_FTM0();
And the above function is defined as follows:
void lin_application_timer_FTM0()
{
SIM_SCGC |= SIM_SCGC_FTM0_MASK; /* Enable Clock for FTM0 */
FTM0_SC |= FTM_SC_PS(7); /* Select Preescaler in this case 128. 20 Mhz /128 =156.25 Khz. */
/* Counter increase by one every 6.4 us */
/* Enable Channle 0*/
FTM0_C0SC |= FTM_CnSC_CHIE_MASK; /* Enable channel 0 interrupt */
FTM0_C0SC |= FTM_CnSC_MSA_MASK; /* Channel as Output compare mode */
/*Select interrupt frequency*/
FTM0_C0V = FTM_CnV_VAL(391) ; /* Interrupt every 2.5ms */
FTM0_SC |= FTM_SC_CLKS(1); /*FTM0 use system clock*/
/* Set the ICPR and ISER registers accordingly */
NVIC_ICPR |= 1 << ((INT_FTM0-16)%32);
NVIC_ISER |= 1 << ((INT_FTM0-16)%32);
}
Can anyone explain why is the LED0 toggling without any interrupt?
It’s possible that the interrupt is actually being triggered. Does your interrupt pin have a pull up or pull-down resistor attached? If it’s disconnected and just “floating”, electrical noise in the environment can cause spurious interrupts.