Creating a buffer in Nusmv - asynchronous

I'm attempting to write code for a buffer in NuSMV. The buffer has 6 wires. 4 input wires (reset, clock, read_enable, and write_enable) and 2 output wires(full and empty). Wires are modeled as boolean true|false (true being high voltage). The first
wire is an asynchronous (instant) reset. If there is a high voltage, the buffer
goes instantly to the empty configuration. Other wires are operated in the
synchronous mode triggered by a rising edge on the clock wire. The buffer is of Size 3. There are specific behaviors.
I created the following code but I cannot think of what the Main Module could be.
MODULE buffer (reset, clock, read_enable, write_enable, full, empty)
-- inputs
-- reset : boolean; -- asynchronous (instant) reset
-- clock : boolean; -- clock
-- read_enable : boolean; -- data read request = enqueue
-- write_enable : boolean; -- data write request = dequeue
-- outputs
-- full : boolean; -- is the buffer full?
-- empty : boolean; -- is the buffer empty?
-- use SIZE for the maximal buffer size
-- TODO ....
VAR
reset: {False, True};
clock: {False, True};
read_enable: {False, True};
write_enable: {False, True};
full: {False, True};
empty: {False, True};
ASSIGN
SIZE := 0;
init (reset) := True;
next (reset) := case
reset = True : empty = True;
esac;
next (clock) := case
write_enable = True : clock = True & empty = False;
esac;
next (write_enable):= case
write_enable = True : SIZE + 1 & SIZE <=3;
esac;
next (read_enable) := case
write_enable = True & read_enable = True : SIZE != SIZE +1;
esac;
next (full) := case
full = True & SIZE = 3 & write_enable = True : reset = True;
esac;
MODULE main
VAR
reset: boolean;
turn: boolean;
pro0: process buffer(reset, 0, clock, read_enable, write_enable);
pro1: process buffer(reset, 1, clock, read_enable, write_enable);
ASSIGN
init(turn) := 0;
FAIRNESS !(reset = True)
FAIRNESS !(reset = False)
MODULE prc(reset, turn, pro0, pro1)
ASSIGN
init(reset) := 0;
next (reset) := case
(reset = 0) : {0,1};
(reset = 1) : {0};
1 : reset;
esac;
Please assist
I've tried following basic NuSMV guides on how to write the code but I have no experience in this language.

Related

Win10 <-> USB <-> Arduino - Problem to communicate with Autohotkey

My desire is to communicate with an Arduino Uno over an USB-port (COM3 - 9600,N,8,1).
I was going to manage the information with Autohotkey on a computer running Windows 10.
This test is only intended to read the information from the Arduino. But later I also want to be able to send information from the PC to the Arduino Uno.
The Arduino Uno has an extra card attached (Funduino JoyStick Shield V1.A) - only for the test.
This is the program I use on the Arduino .:
// Armuino --- Funduino Joystick Shield ---
// Playlist: https://www.youtube.com/playlist?list=PLRFnGJH1nJiKIpz_ZyaU-uAZOkMH8GAcw
//
// Part 1. Introduction - Basic Functions: https://www.youtube.com/watch?v=lZPZuBCFMH4
// Arduino digital pins associated with buttons
const byte PIN_BUTTON_A = 2;
const byte PIN_BUTTON_B = 3;
const byte PIN_BUTTON_C = 4;
const byte PIN_BUTTON_D = 5;
const byte PIN_BUTTON_E = 6;
const byte PIN_BUTTON_F = 7;
// Arduino analog pins associated with joystick
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
void setup() {
Serial.begin(9600);
pinMode(PIN_BUTTON_B, INPUT);
digitalWrite(PIN_BUTTON_B, HIGH);
pinMode(PIN_BUTTON_E, INPUT);
digitalWrite(PIN_BUTTON_E, HIGH);
pinMode(PIN_BUTTON_C, INPUT);
digitalWrite(PIN_BUTTON_C, HIGH);
pinMode(PIN_BUTTON_D, INPUT);
digitalWrite(PIN_BUTTON_D, HIGH);
pinMode(PIN_BUTTON_A, INPUT);
digitalWrite(PIN_BUTTON_A, HIGH);
}
void loop() {
Serial.print("Buttons A:");
Serial.print(digitalRead(PIN_BUTTON_A));
Serial.print(" ");
Serial.print("B:");
Serial.print(digitalRead(PIN_BUTTON_B));
Serial.print(" ");
Serial.print("C:");
Serial.print(digitalRead(PIN_BUTTON_C));
Serial.print(" ");
Serial.print("D:");
Serial.print(digitalRead(PIN_BUTTON_D));
Serial.print(" ");
Serial.print("E:");
Serial.print(digitalRead(PIN_BUTTON_E));
Serial.print(" ");
Serial.print("F:");
Serial.print(digitalRead(PIN_BUTTON_F));
Serial.print(" -- ");
Serial.print("Position X:");
Serial.print(analogRead(PIN_ANALOG_X));
Serial.print(" ");
Serial.print("Y:");
Serial.print(analogRead(PIN_ANALOG_Y));
Serial.print(" ");
Serial.println();
delay(1000);
}
This program seems to work when I run the Arduino Serial Editor on the PC.
The values is coming row for row on the screen, like this .:
**00:58:44.434 -> Buttons A:1 B:1 C:1 D:1 E:1 F:1 -- Position X:334 Y:321**
(I can't see any wrong values in the Serial Editor. - maybe in higher speed)
But if I try to "do the same" with Autohotkey, characters may be missing - some times.
Like this .:
But:322
Buttons A:1 B:1 C:1 D:1 E:1 F:1 -- Position X:334 Y:322
334 Y:322
Buttons A:1 B:1 C:1 D:1 E:1 F:1 -- Position X:334 Y:322
I have no idea how the communication with USB should look like in Windows 10.
(I think it is not the same as eg. Windows XP)
I have looked on this solution .: Arduino + AutoHotKey > Serial Connection
- Not sure I found the right Arduino.ahk
- Maybe require Windows XP?
- It doesn't work for me!
This tip is better (but old) .: Arduino.ahk beta .01
The most of tests have been based on this link and I created the following AHK-program .:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#Singleinstance force
COM = 3
Num_Bytes = 500
Mode =
; Initialize COM-port
COM_Port = COM%COM%
COM_Baud = 9600
COM_Parity = N
COM_Data = 8
COM_Stop = 1
COM_DTR = Off
FilNamn := A_ScriptDir "/Test.txt"
IfExist %FilNamn%
FileDelete %FilNamn%
COM_Settings = %COM_Port%:baud=%COM_Baud% parity=%COM_Parity% data=%COM_Data% stop=%COM_Stop% dtr=%COM_DTR%
COM_FileHandle := Serial_Initialize(COM_Settings)
Loop 100
{ ; ReadResult := Serial_Read(COM_FileHandle, Num_Bytes, Mode)
ReadResult := Serial_Read_Raw(COM_FileHandle, Num_Bytes, Mode)
asciiString := Hex2ASCII(ReadResult)
sleep 20
FileAppend %asciiString%, %FilNamn%, UTF-8
; SplashTextOn 800, 100, Arduino Read, %asciiString%
; Sleep 1000
; MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, % COM_Settings "`n`n" ReadResult "`n`n- " StrLen(ReadResult) "`n`n- " Bytes_Received "`n`n- " asciiString, 1
}
Serial_Close(COM_FileHandle)
; MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, % COM_Settings "`n`n" ReadResult "`n`n- " StrLen(ReadResult) "`n`n- " Bytes_Received
; asciiString := Hex2ASCII(ReadResult)
; MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, % ReadResult "`n`n"asciiString
MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, Klart!
ExitApp
ESC::
SplashTextOff
Serial_Close(COM_FileHandle)
MsgBox ,,, Programmet avslutas!, 1
ExitApp
Return
Hex2ASCII(fHexString)
{ Loop Parse, fHexString
NewHexString .= A_LoopField (Mod(A_Index,2) ? "" : ",")
Loop Parse, NewHexString, `,
ConvString .= Chr("0x" A_LoopField)
Return ConvString
} ;http://www.autohotkey.com/forum/post-211769.html#211769
;########################################################################
;###### Initialize COM Subroutine #######################################
;########################################################################
Serial_Initialize(SERIAL_Settings){
;Global SERIAL_FileHandle ;uncomment this if there is a problem
;###### Build COM DCB ######
;Creates the structure that contains the COM Port number, baud rate,...
VarSetCapacity(DCB, 28)
BCD_Result := DllCall("BuildCommDCB"
,"str" , SERIAL_Settings ;lpDef
,"UInt", &DCB) ;lpDCB
If (BCD_Result <> 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll BuildCommDCB, BCD_Result=%BCD_Result% `nLasterror=%error%`nThe Script Will Now Exit.
ExitApp
}
;###### Extract/Format the COM Port Number ######
StringSplit, SERIAL_Port_Temp, SERIAL_Settings, `:
SERIAL_Port_Temp1_Len := StrLen(SERIAL_Port_Temp1) ;For COM Ports > 9 \\.\ needs to prepended to the COM Port name.
If (SERIAL_Port_Temp1_Len > 4) ;So the valid names are
SERIAL_Port = \\.\%SERIAL_Port_Temp1% ; ... COM8 COM9 \\.\COM10 \\.\COM11 \\.\COM12 and so on...
Else ;
SERIAL_Port = %SERIAL_Port_Temp1%
;MsgBox, SERIAL_Port=%SERIAL_Port%
;###### Create COM File ######
;Creates the COM Port File Handle
;StringLeft, SERIAL_Port, SERIAL_Settings, 4 ; 7/23/08 This line is replaced by the "Extract/Format the COM Port Number" section above.
SERIAL_FileHandle := DllCall("CreateFile"
,"Str" , SERIAL_Port ;File Name
,"UInt", 0xC0000000 ;Desired Access
,"UInt", 3 ;Safe Mode
,"UInt", 0 ;Security Attributes
,"UInt", 3 ;Creation Disposition
,"UInt", 0 ;Flags And Attributes
,"UInt", 0 ;Template File
,"Cdecl Int")
If (SERIAL_FileHandle < 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll CreateFile, SERIAL_FileHandle=%SERIAL_FileHandle% `nLasterror=%error%`nThe Script Will Now Exit.
ExitApp
}
;###### Set COM State ######
;Sets the COM Port number, baud rate,...
SCS_Result := DllCall("SetCommState"
,"UInt", SERIAL_FileHandle ;File Handle
,"UInt", &DCB) ;Pointer to DCB structure
If (SCS_Result <> 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll SetCommState, SCS_Result=%SCS_Result% `nLasterror=%error%`nThe Script Will Now Exit.
Serial_Close(SERIAL_FileHandle)
ExitApp
}
;###### Create the SetCommTimeouts Structure ######
ReadIntervalTimeout = 0xffffffff
ReadTotalTimeoutMultiplier = 0x00000000
ReadTotalTimeoutConstant = 0x00000000
WriteTotalTimeoutMultiplier= 0x00000000
WriteTotalTimeoutConstant = 0x00000000
VarSetCapacity(Data, 20, 0) ; 5 * sizeof(DWORD)
NumPut(ReadIntervalTimeout, Data, 0, "UInt")
NumPut(ReadTotalTimeoutMultiplier, Data, 4, "UInt")
NumPut(ReadTotalTimeoutConstant, Data, 8, "UInt")
NumPut(WriteTotalTimeoutMultiplier, Data, 12, "UInt")
NumPut(WriteTotalTimeoutConstant, Data, 16, "UInt")
;###### Set the COM Timeouts ######
SCT_result := DllCall("SetCommTimeouts"
,"UInt", SERIAL_FileHandle ;File Handle
,"UInt", &Data) ;Pointer to the data structure
If (SCT_result <> 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll SetCommState, SCT_result=%SCT_result% `nLasterror=%error%`nThe Script Will Now Exit.
Serial_Close(SERIAL_FileHandle)
ExitApp
}
Return SERIAL_FileHandle
}
;########################################################################
;###### Close COM Subroutine ############################################
;########################################################################
Serial_Close(SERIAL_FileHandle){
;###### Close the COM File ######
CH_result := DllCall("CloseHandle", "UInt", SERIAL_FileHandle)
If (CH_result <> 1)
MsgBox, Failed Dll CloseHandle CH_result=%CH_result%
Return
}
;########################################################################
;###### Write to COM Subroutines ########################################
;########################################################################
Serial_Write(SERIAL_FileHandle, Message){
;Global SERIAL_FileHandle
OldIntegerFormat := A_FormatInteger
SetFormat, Integer, DEC
;Parse the Message. Byte0 is the number of bytes in the array.
StringSplit, Byte, Message, `,
Data_Length := Byte0
;msgbox, Data_Length=%Data_Length% b1=%Byte1% b2=%Byte2% b3=%Byte3% b4=%Byte4%
;Set the Data buffer size, prefill with 0xFF.
VarSetCapacity(Data, Byte0, 0xFF)
;Write the Message into the Data buffer
i=1
Loop %Byte0% {
NumPut(Byte%i%, Data, (i-1) , "UChar")
;msgbox, %i%
i++
}
;msgbox, Data string=%Data%
;###### Write the data to the COM Port ######
WF_Result := DllCall("WriteFile"
,"UInt" , SERIAL_FileHandle ;File Handle
,"UInt" , &Data ;Pointer to string to send
,"UInt" , Data_Length ;Data Length
,"UInt*", Bytes_Sent ;Returns pointer to num bytes sent
,"Int" , "NULL")
If (WF_Result <> 1 or Bytes_Sent <> Data_Length)
MsgBox, Failed Dll WriteFile to COM Port, result=%WF_Result% `nData Length=%Data_Length% `nBytes_Sent=%Bytes_Sent%
SetFormat, Integer, %OldIntegerFormat%
Return Bytes_Sent
}
;########################################################################
;###### Read from COM Subroutines #######################################
;########################################################################
;########################################################################
;###### Read from COM Subroutines #######################################
;########################################################################
Serial_Read(COM_FileHandle, Num_Bytes, mode = "",byref Bytes_Received = "")
{
;Global COM_FileHandle
;Global COM_Port
;Global Bytes_Received
SetFormat, Integer, HEX
;Set the Data buffer size, prefill with 0x55 = ASCII character "U"
;VarSetCapacity won't assign anything less than 3 bytes. Meaning: If you
; tell it you want 1 or 2 byte size variable it will give you 3.
Data_Length := VarSetCapacity(Data, Num_Bytes, 0x55)
;msgbox, Data_Length=%Data_Length%
;###### Read the data from the COM Port ######
;msgbox, COM_FileHandle=%COM_FileHandle% `nNum_Bytes=%Num_Bytes%
Read_Result := DllCall("ReadFile"
,"UInt" , COM_FileHandle ; hFile
,"Str" , Data ; lpBuffer
,"Int" , Num_Bytes ; nNumberOfBytesToRead
,"UInt*", Bytes_Received ; lpNumberOfBytesReceived
,"Int" , 0) ; lpOverlapped
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData=%Data%
If (Read_Result <> 1)
{
MsgBox, There is a problem with Serial Port communication. `nFailed Dll ReadFile on COM Port, result=%Read_Result% - The Script Will Now Exit.
Serial_Close(COM_FileHandle)
Exit
}
;if you know the data coming back will not contain any binary zeros (0x00), you can request the 'raw' response
If (mode = "raw")
Return Data
;###### Format the received data ######
;This loop is necessary because AHK doesn't handle NULL (0x00) characters very nicely.
;Quote from AHK documentation under DllCall:
; "Any binary zero stored in a variable by a function will hide all data to the right
; of the zero; that is, such data cannot be accessed or changed by most commands and
; functions. However, such data can be manipulated by the address and dereference operators
; (& and *), as well as DllCall itself."
i = 0
Data_HEX =
Loop %Bytes_Received%
{
;First byte into the Rx FIFO ends up at position 0
Data_HEX_Temp := NumGet(Data, i, "UChar") ;Convert to HEX byte-by-byte
StringTrimLeft, Data_HEX_Temp, Data_HEX_Temp, 2 ;Remove the 0x (added by the above line) from the front
;If there is only 1 character then add the leading "0'
Length := StrLen(Data_HEX_Temp)
If (Length =1)
Data_HEX_Temp = 0%Data_HEX_Temp%
i++
;Put it all together
Data_HEX .= Data_HEX_Temp
}
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData_HEX=%Data_HEX%
SetFormat, Integer, DEC
Data := Data_HEX
Return Data
}
;########################################################################
;###### Read from COM Subroutines #######################################
;########################################################################
Serial_Read_Raw(SERIAL_FileHandle, Num_Bytes, mode = "",byref Bytes_Received = ""){
;Global SERIAL_FileHandle
;Global SERIAL_Port
;Global Bytes_Received
OldIntegerFormat := A_FormatInteger
SetFormat, Integer, HEX
;Set the Data buffer size, prefill with 0x55 = ASCII character "U"
;VarSetCapacity won't assign anything less than 3 bytes. Meaning: If you
; tell it you want 1 or 2 byte size variable it will give you 3.
Data_Length := VarSetCapacity(Data, Num_Bytes, 0)
;msgbox, Data_Length=%Data_Length%
;###### Read the data from the COM Port ######
;msgbox, SERIAL_FileHandle=%SERIAL_FileHandle% `nNum_Bytes=%Num_Bytes%
Read_Result := DllCall("ReadFile"
,"UInt" , SERIAL_FileHandle ; hFile
,"Str" , Data ; lpBuffer
,"Int" , Num_Bytes ; nNumberOfBytesToRead
,"UInt*", Bytes_Received ; lpNumberOfBytesReceived
,"Int" , 0) ; lpOverlapped
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData=%Data%
If (Read_Result <> 1){
MsgBox, There is a problem with Serial Port communication. `nFailed Dll ReadFile on COM Port, result=%Read_Result% - The Script Will Now Exit.
Serial_Close(SERIAL_FileHandle)
Exit
}
;if you know the data coming back will not contain any binary zeros (0x00), you can request the 'raw' response
If (mode = "raw")
Return Data
;###### Format the received data ######
;This loop is necessary because AHK doesn't handle NULL (0x00) characters very nicely.
;Quote from AHK documentation under DllCall:
; "Any binary zero stored in a variable by a function will hide all data to the right
; of the zero; that is, such data cannot be accessed or changed by most commands and
; functions. However, such data can be manipulated by the address and dereference operators
; (& and *), as well as DllCall itself."
i = 0
Data_HEX =
Loop %Bytes_Received%
{
;First byte into the Rx FIFO ends up at position 0
Data_HEX_Temp := NumGet(Data, i, "UChar") ;Convert to HEX byte-by-byte
StringTrimLeft, Data_HEX_Temp, Data_HEX_Temp, 2 ;Remove the 0x (added by the above line) from the front
;If there is only 1 character then add the leading "0'
Length := StrLen(Data_HEX_Temp)
If (Length =1)
Data_HEX_Temp = 0%Data_HEX_Temp%
i++
;Put it all together
Data_HEX .= Data_HEX_Temp
}
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData_HEX=%Data_HEX%
SetFormat, Integer, DEC
Data := Data_HEX
SetFormat, Integer, %OldIntegerFormat%
Return Data
}
Thanks for your time!
Has managed to get better communication between Windows and the Arduino. (with a different configuration).Made two windows in a GUI
One where I can enter characters.
Arduinon echoes back what is typed and returns that character to the PC
The other show the returned characters..
It works (in 9600bps), but first I send a headline and if the baud rate increases, "strange" characters always appear at the beginning of the test.
Don't know if the serial buffer in the Arduino / PC needs to be cleared before the characters start to read in sharp mode? (how to do that?)
In the Arduino SerialMonitor I got not readable information with higher baudrate (from another test program)
My ECHO-program in the Arduino
int incomingByte;
void setup() {
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
incomingByte = Serial.read();
//Serial.print(incomingByte);
Serial.write(incomingByte);
}
}

Cortex-M0+ : Can't Jump From Bootloader To App

I'm Working on ATSAMC21 (ATSAMC21J18A) with Cortex-M0+, making my CAN bootloader.My IDE is ATMEL studio.
Flashing my app is Ok but when I jump in i, it failed.(I tryed with debug and without)
In dissaseembly it point to the first of these two line:
*FFFFFFFE ?? ?? ??? Memory out of bounds or read error*
*00000000 a0.32 adds r2, #160*
pc disassembly point
My bootloader space in my linker :
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
My application (or firmware) space in my linker :
MEMORY
{
rom (rx) : ORIGIN = 0x00010000, LENGTH = 0x00030000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
Before jumping,
I disabled irq interrupt, defined my entry point and my stack pointer, and change VTOR.
Here is my code to jump:
void JumpToApp(void) {
uint16_t i;
uint32_t startAddress, applicationStack;
/* Check if WDT is locked */
if (!(WDT->CTRLA.reg & WDT_CTRLA_ALWAYSON)) {
/* Disable the Watchdog module */
WDT->CTRLA.reg &= ~WDT_CTRLA_ENABLE;
}
//stop general IT
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
// Pointer to the Application Section
void (*application_code_entry)(void);
startAddress = FLASH_APP_VADRESS; //HERE 0x00010000, my start App
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS + 4)); //HERE 0x00010004
// Rebase the Stack Pointer
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack); //HERE 0x00010000, my start App
// Rebase the vector table base address
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
// Jump to user Reset Handler in the application
application_code_entry();
}
I tried to add +1 at my application_code_entry , like a odd Thumb mode, i see this for Cortex-M3 but it don't work, fail in general IT.
Then I rename main() by main_boot()
and Reset_Handler() by Reset_Handler_Boot() (and by changing in propety flag linker the --entry=Reset_Handler_Boot)
But still not jumping.
I don't know what i'm doing bad.May be there is a long jump to do?
Split the RAM?
If somebody have an idea?
Thank You!!!!!!!!!!!!!!!!!!!
Thank you, (it was a mistake :) )but this hard fault doesn't resolve my jump (in fact i Used directly the adress __set_MSP(*(uint32_t *)(FLASH_APP_VADRESS));
My MSP is not 0x0000000, it's 0x20003240 so is it an offset to apply to my new MSP? (see the picture linked)
Here is my code for testing the MSP
ReadMsp=__get_MSP(); //result 0x20003240, before change it
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0xFFFFFFFC , why ???
__DSB();
__ISB();
__set_MSP(0x00010000);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0x00010000, better than my same #define FLASH_APP_VADRESS or *(uint32_t *)applicationStack in __MSP
//applicationEntry();
// Load the Reset Handler address of the application
//application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS ));
// Jump to user Reset Handler in the application
application_code_entry();
Should I use (0x20003240 + 0x00010000) for my new MSP?
enter image description here
You are dereferencing the SP stack pointer twice:
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
// ... --^
__set_MSP(*(uint32_t *)applicationStack);
// -^
You need to do that only once. The second time sets SP highly likely to zero, resulting to a fault once the stack is used.
I found the answer !!!
Finally to jump, just like atmel say BUT before I needed to uninitialized some module.
So : ATMEL part :
*// Pointer to the Application Section
void (*application_code_entry)(void);
// Rebase the Stack Pointer
__set_MSP(*(uint32_t *)FLASH_APP_VADRESS);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)FLASH_APP_VADRESS & SCB_VTOR_TBLOFF_Msk);
// Load the Reset Handler address of the application
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)
(FLASH_APP_VADRESS + 4));
// Jump to user Reset Handler in the application
application_code_entry();*
My part before executing this :
*Flash_Deinit(); //flash uninit
config_TC_Deinit(); //time clock uninit, scheduler
can_deinit0(); // module CAN0
can_deinit1(); // module CAN1
Handle_Wdt_Disable();
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->IP[i] = 0x00000000;
}
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;*
I hope it will help someone !!! :)

VHDL clock generator with different speeds using button

I am new to VHDL and currently working on a clock generator that generates two different clock speeds.
Everything is working, except the switch between the slow and fast speed_status.
There seems to be a problem with the "speed button" because sometimes I have to press it more than once to change the current set speed. The "reset button" is always working as expected. Is there something wrong with my VHDL Code or do I need to add some sort of software debouncing? If so, why is the reset button working?
And could you give me some advice which parts of my clock generator I could improve (code/logic)?
entity clk_gen is
Port ( clk_in : in STD_LOGIC;
clk_btn_in : in STD_LOGIC_VECTOR (3 DOWNTO 0);
clk_out : out STD_LOGIC);
end clk_gen;
architecture Behavioral of clk_gen is
signal temp : STD_LOGIC := '0';
begin
clock: process(clk_in,clk_btn_in)
variable counter : integer range 0 to 49999999 := 0;
constant freq_cnt_slow : integer := 49999999;
constant freq_cnt_fast : integer := 4999999;
type speed is (slow, fast);
variable speed_status : speed := slow;
begin
if rising_edge(clk_in) then
-- RESET BUTTON PRESSED
if (clk_btn_in = "1000") then
temp <= '0';
counter := 0;
speed_status := slow;
-- SPEED BUTTON
elsif (clk_btn_in = "0100") then
if (speed_status = fast) then
speed_status:= slow;
elsif (speed_status = slow) then
speed_status := fast;
end if;
end if;
if ((counter = freq_cnt_fast) and (speed_status = fast)) then
temp <= NOT(temp);
counter := 0;
elsif ((counter = freq_cnt_slow) and (speed_status = slow)) then
temp <= NOT(temp);
counter := 0;
else
counter := counter + 1;
end if;
end if;
end process clock;
clk_out <= temp;
end Behavioral;
I use Xilinx ISE 13.4 and the XC5VLX110T based on Xilinx Virtex 5.
It looks like your speed mode will toggle any time the button is in the 'pressed' state. Unless you can guarantee that your button is only 'pressed' for one clock period, the state is likely to toggle many times, making the state after you pressed the button essentially random (depending on the exact timing of the button press).
Firstly, you need a debouncing circuit on the button. This can be implemented externally, or within the FPGA. I will not go into switch debouncing in detail here, but you can easily find information on this elsewhere. Secondly, you need to convert the button into a synchronous signal, that is, one that has a fixed relationship to your clock. An example synchroniser for your example would be:
signal button_reg1 : std_logic_vector(3 downto 0) := (others => '0');
signal button_reg2 : std_logic_vector(3 downto 0) := (others => '0');
...
process (clk_in)
begin
if (rising_edge(clk_in)) then
button_reg2 <= button_reg1;
button_reg1 <= clk_btn_in;
end if;
end process;
button_reg2 will then have a fixed relationship to the clock.
Without this, you could violate the setup/hold constraints on the speed_status register. Lastly, you need to convert the pressing of the button into a pulse that is one clock period in length. Example:
signal speed_button_reg : std_logic := '0';
signal speed_button_pressed : std_logic := '0';
...
process (clk_in)
begin
if (rising_edge(clk_in)) then
speed_button_reg <= button_reg2(2);
if (speed_button_reg = '0' and button_reg2(2) = '1') then
-- The button has just been pressed (gone from low to high)
-- Do things here, or set another signal e.g.
speed_button_pressed <= '1';
else
speed_button_pressed <= '0';
end if;
end if;
end process;

VHDL RS-232 Receiver

I have been trying to design an RS-232 receiver taking an FSM approach. I will admit that I do not have a very well-rounded understanding of VHDL, so I have been working on the code on the fly and learning as I go. However, I believe I've hit a brick wall at this point.
My issue is that I have two processes in my code, one to trigger the next state and the other to perform the combinational logic. My code is as follows:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ASyncReceiverV4 is
Port ( DataIn : in STD_LOGIC;
Enable : in STD_LOGIC;
CLK : in STD_LOGIC;
BadData : out STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (7 downto 0));
end ASyncReceiverV4;
architecture Behavioral of ASyncReceiverV4 is
type states is (StartBitCheck, ReadData, StopBitCheck);
signal currentState, nextState : states;
begin
process(CLK)
begin
if rising_edge(CLK) then
currentState <= nextState;
end if;
end process;
process(CLK)
variable counter : integer := 0;
variable dataIndex : integer := 0;
begin
case currentState is
when StartBitCheck =>
if Enable = '1' then
if (DataIn = '0' and counter < 8) then
counter := counter + 1;
elsif (DataIn = '0' and counter = 8) then
BadData <= '0';
nextState <= ReadData;
counter := 0;
else
nextState <= StartBitCheck;
end if;
end if;
when ReadData =>
if Enable = '1' then
if counter < 16 then
counter := counter + 1;
elsif (counter = 16 and dataIndex < 8) then
DataOut(dataIndex) <= DataIn;
counter := 0;
dataIndex := dataIndex + 1;
elsif dataIndex = 8 then
dataIndex := 0;
nextState <= StopBitCheck;
else
nextState <= ReadData;
end if;
end if;
when StopBitCheck =>
if Enable = '1' then
if DataIn = '1' then
if counter < 16 then
counter := counter + 1;
nextState <= StopBitCheck;
elsif counter = 16 then
counter := 0;
nextState <= StartBitCheck;
end if;
else
DataOut <= "11111111";
BadData <= '1';
nextState <= StartBitCheck;
end if;
end if;
end case;
end process;
end Behavioral;
For whatever reason, based on my simulations, it seems that my processes are out of sync. Although things are only supposed to occur at the rising edge of the clock, I have transitions occurring at the falling edge. Furthermore, it seems like things are not changing according to the value of counter.
The Enable input is high in all of my simulations. However, this is just to keep it simple for now, it will eventually be fed the output of a 153,600 Baud generator (the Baud generator will be connected to the Enable input). Hence, I only want things to change when my Baud generator is high. Otherwise, do nothing. Am I taking the right approach for that with my code?
I can supply a screenshot of my simulation if that would be helpful. I am also not sure if I am including the correct variables in my process sensitivity list. Also, am I taking the right approach with my counter and dataIndex variables? What if I made them signals as part of my architecture before any of my processes?
Any help on this would be very much so appreciated!
The easiest way to fix this, while also producing the easiest to read code, would be to move to a 1-process state machine like so (warning: not complied may contain syntax errors):
entity ASyncReceiverV4 is
Port ( DataIn : in STD_LOGIC;
Enable : in STD_LOGIC;
CLK : in STD_LOGIC;
BadData : out STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (7 downto 0));
end ASyncReceiverV4;
architecture Behavioral of ASyncReceiverV4 is
type states is (StartBitCheck, ReadData, StopBitCheck);
signal state : states := StartBitCheck;
signal counter : integer := 0;
signal dataIndex : integer := 0;
begin
process(CLK)
begin
if rising_edge(CLK) then
case state is
when StartBitCheck =>
if Enable = '1' then
if (DataIn = '0' and counter < 8) then
counter <= counter + 1;
elsif (DataIn = '0' and counter = 8) then
BadData <= '0';
state <= ReadData;
counter <= 0;
end if;
end if;
when ReadData =>
if Enable = '1' then
if counter < 16 then
counter <= counter + 1;
elsif (counter = 16 and dataIndex < 8) then
DataOut(dataIndex) <= DataIn;
counter <= 0;
dataIndex <= dataIndex + 1;
elsif dataIndex = 8 then
dataIndex <= 0;
state <= StopBitCheck;
end if;
end if;
when StopBitCheck =>
if Enable = '1' then
if DataIn = '1' then
if counter < 16 then
counter <= counter + 1;
elsif counter = 16 then
counter <= 0;
state <= StartBitCheck;
end if;
else
DataOut <= "11111111";
BadData <= '1';
state <= StartBitCheck;
end if;
end if;
end case;
end if;
end process;
end Behavioral;
Note that while this no longer contains language issues, there are still odd things in the logic.
You cannot enter the state StopBitCheck until counter is 16 because the state transition is in an elsif of counter < 16. Therefore, the if counter < 16 in StopBitCheck is unreachable.
Also note that the state transition to StopBitCheck happens on the same cycle that you would normally sample data, so the sampling of DataIn within StopBitCheck will be a cycle late. Worse, were you ever to get bad data (DataIn/='1' in StopBitCheck), counter would still be at 16, StartBitCheck would always go to the else clause, and the state machine would lock up.
Some more explanation on what was wrong before:
Your simulation has things changing on the negative clock edge because your combinatorial process only has the clock on the sensitivity list. The correct sensitivity list for the combinatorial process would include only DataIn, Enable, currentState, and your two variables, counter and dataIndex. Variables can't be a part of your sensitivity list because they are out of scope for the sensitivity list (also you do not want to trigger your process off of itself, more on that in a moment).
The sensitivity list is, however, mostly just a crutch for simulators. When translated to real hardware, processes are implemented in LUTs and Flip Flops. Your current implementation will never synthesize because you incorporate feedback (signals or variables that get assigned a new value as a function of their old value) in unclocked logic, producing a combinatorial loop.
counter and dataIndex are part of your state data. The state machine is simpler to understand because they are split off from the explicit state, but they are still part of the state data. When you make a two process state machine (again, I recommend 1 process state machines, not 2) you must split all state data into Flip Flops used to store it (such as currentState) and the output of the LUT that generates the next value (such as nextState). This means that for your two process machine, the variables counter and dataIndex must instead become currentCounter, nextCounter, currentDataIndex, and nextDataIndex and treated like your state assignment. Note that if you choose to implement changes to keep a 2-process state machine, the logic errors mentioned above the line will still apply.
EDIT:
Yes, resetting the counter back to 0 before moving into StopBitCheck might be a good idea, but you also need to consider that you are waiting the full 16 counts after sampling the last data bit before you even transition into StopBitCheck. It is only because counter is not reset that the sample is only off by one clock instead of 16. You may want to modify your ReadData action to transition to StopBitCheck as you sample the last bit when dataIndex=7 (as well as reset counter to 0) like so:
elsif (counter = 16) then
DataOut(dataIndex) <= DataIn;
counter <= 0;
if (dataIndex < 7) then
dataIndex <= dataIndex + 1;
else
dataIndex <= 0;
state <= StopBitCheck;
end if;
end if;
A pure state machine only stores a state. It generates its output purely from the state, or from a combination of the state and the inputs. Because counter and dataIndex are stored, they are part of the state. If you wanted to enumerate every single state you would have something like:
type states is (StartBitCheck_Counter0, StartBitCheck_counter1...
and you would end up with 8*16*3 = 384 states (actually somewhat less because only ReadData uses dataIndex, so some of the 384 are wholly redundant states). As you can no doubt see, it is much simpler to just declare 3 separate signals since the different parts of the state data are used differently. In a two process state machine, people often forget that the signal actually named state isn't the only state data that needs to be stored in the clocked process.
In a 1-process machine, of course, this isn't an issue because everything that is assigned is by necessity stored in flip flops (the intermediary combinational logic isn't enumerated in signals). Also, do note that 1-process state machines and 2-process state machines will synthesize to the same thing (assuming they were both implemented correctly), although I'm of the opinion that is comparatively easier to read and more difficult to mess up a 1-process machine.
I also removed the else clauses that maintained the current state assignment in the 1-process example I provided; they are important when assigning a combinational nextState, but the clocked signal state will keep its old value whenever it isn't given a new assignment without inferring a latch.
First Process runs just on CLK rising edge, while the second one runs on both CLK edge (because runs on every CLK change).
You use 2 process, “memory-state” and “next-state builder”, the first must be synchronous (as you done) and the second, normally, is combinatorial to be able to produce next-state in time for next CLK active edge.
But in your case the second process needs also to run on every CLK pulse (because of variable counter and index), so the solution can be to run the first on rising-edge and the second on falling-edge (if your hardware support this).
Here is your code a little bit revisited, I hope can be useful.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ASyncReceiverV4 is
Port ( DataIn : in STD_LOGIC;
Enable : in STD_LOGIC;
CLK : in STD_LOGIC;
BadData : out STD_LOGIC := '0';
DataOut : out STD_LOGIC_VECTOR (7 downto 0) := "00000000");
end ASyncReceiverV4;
architecture Behavioral of ASyncReceiverV4 is
type states is (StartBitCheck, ReadData, StopBitCheck);
signal currentState : states := StartBitCheck;
signal nextState : states := StartBitCheck;
begin
process(CLK)
begin
if rising_edge(CLK) then
currentState <= nextState;
end if;
end process;
process(CLK)
variable counter : integer := 0;
variable dataIndex : integer := 0;
begin
if falling_edge(CLK) then
case currentState is
when StartBitCheck =>
if Enable = '1' then
if (DataIn = '0' and counter < 8) then
counter := counter + 1;
elsif (DataIn = '0' and counter = 8) then
BadData <= '0';
nextState <= ReadData;
counter := 0;
else
nextState <= StartBitCheck;
end if;
end if;
when ReadData =>
if Enable = '1' then
if counter < 15 then
counter := counter + 1;
elsif (counter = 15 and dataIndex < 8) then
DataOut(dataIndex) <= DataIn;
counter := 0;
dataIndex := dataIndex + 1;
elsif dataIndex = 8 then
dataIndex := 0;
nextState <= StopBitCheck;
else
nextState <= ReadData;
end if;
end if;
when StopBitCheck =>
if Enable = '1' then
if DataIn = '1' then
if counter < 15 then
counter := counter + 1;
nextState <= StopBitCheck;
elsif counter = 15 then
counter := 0;
nextState <= StartBitCheck;
end if;
else
DataOut <= "11111111";
BadData <= '1';
nextState <= StartBitCheck;
end if;
end if;
end case;
end if;
end process;
end Behavioral;
This is a 0x55 with wrong stop bit receive data simulation

MSP430 Real time clock (RTC_B) doesn't work. Cannot write date/time registers

I'm trying to set date/time registers using the RTC_B module of MSP430F5338 microcontroller.
I'm doing it like this:
RTCCTL0 = 0;
RTCCTL1 |= RTCHOLD +RTCBCD;
RTCHOUR = 0x14;
RTCCTL1 &= ~RTCHOLD;
It doesn't work, and simply ignore the assignements. I cannot understand why. The only strange thing I've noticed is the RTCOFIFG flag set.
Any idea?
Addendum
This is how I set up clock sources:
void clk_init(){
SetVcoreUp (0x01);
SetVcoreUp (0x02);
SetVcoreUp (0x03);
UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation
UCSCTL2 = FLLD_1 | ((f_SMCLK/f_ACLK) -1); // Set DCO Multiplier for 25MHz
// (N + 1) * FLLRef = Fdco
// (762 + 1) * 32768 = 25MHz
// Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0); // Enable the FLL control loop
// Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
do{
UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
void SetVcoreUp (unsigned int level)
{
// Open PMM registers for write
PMMCTL0_H = PMMPW_H;
// Set SVS/SVM high side new level
SVSMHCTL = SVSHE | SVSHRVL0 * level | SVMHE | SVSMHRRL0 * level;
// Set SVM low side to new level
SVSMLCTL = SVSLE | SVMLE | SVSMLRRL0 * level;
// Wait till SVM is settled
while ((PMMIFG & SVSMLDLYIFG) == 0);
// Clear already set flags
PMMIFG &= ~(SVMLVLRIFG | SVMLIFG);
// Set VCore to new level
PMMCTL0_L = PMMCOREV0 * level;
// Wait till new level reached
if ((PMMIFG & SVMLIFG))
while ((PMMIFG & SVMLVLRIFG) == 0);
// Set SVS/SVM low side to new level
SVSMLCTL = SVSLE | SVSLRVL0 * level | SVMLE | SVSMLRRL0 * level;
// Lock PMM registers for write access
PMMCTL0_H = 0x00;
}
I've SOLVED adding this before clock setup:
while (BAKCTL & LOCKBAK) BAKCTL &= ~LOCKBAK;
Basically this is due to the fact that msp430f5338 has the battery backup system, so you'll need this code before you set XT1 drive ACLK.
Hope this helps.
Having just had a browse through the datasheet - two things:
By setting the RTCBCD flag in RTCCTL1, you're saying you want to use binary-coded decimal, so setting RTCHOUR as 0x0A is nonsense. To write proper BCD for, say, 14:47 (2:47pm), you write the hours as 0x14 and 0x47 as the minutes, i.e., write as you see.
Ensure you're not in low power mode 5 (LPM5) - configuration settings are not retained.
Addendum:
Also, the RTCOFIFG flags says you had a fault with your oscillator, so confirm your circuitry too.

Resources