Storing Latin Characters through Linq 2 SQL on WP7 - windows-phone-7

I am using SQL CE database in WP7. I have a table with nvarchar column.
When I insert entity through linq, I see symbol � stored for latin characters.
Database Connection String: "Data Source=test.sdf;Locale Identifier=1035"
Expected to be stored: Tuulispäät
As seen through SSMS: Tuulisp��t
I tried to set the culture of thread but issue still persists.
When I executed insert SQL statement from SSMS, it gets inserted as expected.
So why is it an issue when inserted with Linq2SQL?
Can someone throw light on what am I missing? Any workarounds or pointers?

You just need to convert your data to UTF8 Encoding.
Use this class for conversion on wp7.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class ISO88591Encoding : Encoding
{
/// <summary>
/// Gets the name registered with the
/// Internet Assigned Numbers Authority (IANA) for the current encoding.
/// </summary>
/// <returns>
/// The IANA name for the current <see cref="System.Text.Encoding"/>.
/// </returns>
public override string WebName
{
get
{
return "iso-8859-1";
}
}
private char? fallbackCharacter;
/// <summary>
/// A character that can be set in order to make the encoding class
/// more fault tolerant. If this property is set, the encoding class will
/// use this property instead of throwing an exception if an unsupported
/// byte value is being passed for decoding.
/// </summary>
public char? FallbackCharacter
{
get { return fallbackCharacter; }
set
{
fallbackCharacter = value;
if (value.HasValue && !charToByte.ContainsKey(value.Value))
{
string msg = "Cannot use the character [{0}] (int value {1}) as fallback value "
+ "- the fallback character itself is not supported by the encoding.";
msg = String.Format(msg, value.Value, (int)value.Value);
throw new EncoderFallbackException(msg);
}
FallbackByte = value.HasValue ? charToByte[value.Value] : (byte?)null;
}
}
/// <summary>
/// A byte value that corresponds to the <see cref="FallbackCharacter"/>.
/// It is used in encoding scenarios in case an unsupported character is
/// being passed for encoding.
/// </summary>
public byte? FallbackByte { get; private set; }
public ISO88591Encoding()
{
FallbackCharacter = '?';
}
/// <summary>
/// Encodes a set of characters from the specified character array into the specified byte array.
/// </summary>
/// <returns>
/// The actual number of bytes written into <paramref name="bytes"/>.
/// </returns>
/// <param name="chars">The character array containing the set of characters to encode.
/// </param><param name="charIndex">The index of the first character to encode.
/// </param><param name="charCount">The number of characters to encode.
/// </param><param name="bytes">The byte array to contain the resulting sequence of bytes.
/// </param><param name="byteIndex">The index at which to start writing the resulting sequence of bytes.
/// </param>
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
return FallbackByte.HasValue
? GetBytesWithFallBack(chars, charIndex, charCount, bytes, byteIndex)
: GetBytesWithoutFallback(chars, charIndex, charCount, bytes, byteIndex);
}
private int GetBytesWithFallBack(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
for (int i = 0; i < charCount; i++)
{
var character = chars[i + charIndex];
byte byteValue;
bool status = charToByte.TryGetValue(character, out byteValue);
bytes[byteIndex + i] = status ? byteValue : FallbackByte.Value;
}
return charCount;
}
private int GetBytesWithoutFallback(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
for (int i = 0; i < charCount; i++)
{
var character = chars[i + charIndex];
byte byteValue;
bool status = charToByte.TryGetValue(character, out byteValue);
if (!status)
{
//throw exception
string msg =
"The encoding [{0}] cannot encode the character [{1}] (int value {2}). Set the FallbackCharacter property in order to suppress this exception and encode a default character instead.";
msg = String.Format(msg, WebName, character, (int)character);
throw new EncoderFallbackException(msg);
}
bytes[byteIndex + i] = byteValue;
}
return charCount;
}
/// <summary>
/// Decodes a sequence of bytes from the specified byte array into the specified character array.
/// </summary>
/// <returns>
/// The actual number of characters written into <paramref name="chars"/>.
/// </returns>
/// <param name="bytes">The byte array containing the sequence of bytes to decode.
/// </param><param name="byteIndex">The index of the first byte to decode.
/// </param><param name="byteCount">The number of bytes to decode.
/// </param><param name="chars">The character array to contain the resulting set of characters.
/// </param><param name="charIndex">The index at which to start writing the resulting set of characters.
/// </param>
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
return FallbackCharacter.HasValue
? GetCharsWithFallback(bytes, byteIndex, byteCount, chars, charIndex)
: GetCharsWithoutFallback(bytes, byteIndex, byteCount, chars, charIndex);
}
private int GetCharsWithFallback(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
for (int i = 0; i < byteCount; i++)
{
byte lookupIndex = bytes[i + byteIndex];
//if the byte value is not in our lookup array, fall back to default character
char result = lookupIndex >= byteToChar.Length
? FallbackCharacter.Value
: byteToChar[lookupIndex];
chars[charIndex + i] = result;
}
return byteCount;
}
private int GetCharsWithoutFallback(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
for (int i = 0; i < byteCount; i++)
{
byte lookupIndex = bytes[i + byteIndex];
if (lookupIndex >= byteToChar.Length)
{
//throw exception
string msg = "The encoding [{0}] cannot decode byte value [{1}]. Set the FallbackCharacter property in order to suppress this exception and decode the value as a default character instead.";
msg = String.Format(msg, WebName, lookupIndex);
throw new EncoderFallbackException(msg);
}
chars[charIndex + i] = byteToChar[lookupIndex];
}
return byteCount;
}
/// <summary>
/// Calculates the number of bytes produced by encoding a set of characters
/// from the specified character array.
/// </summary>
/// <returns>
/// The number of bytes produced by encoding the specified characters. This class
/// alwas returns the value of <paramref name="count"/>.
/// </returns>
public override int GetByteCount(char[] chars, int index, int count)
{
return count;
}
/// <summary>
/// Calculates the number of characters produced by decoding a sequence
/// of bytes from the specified byte array.
/// </summary>
/// <returns>
/// The number of characters produced by decoding the specified sequence of bytes. This class
/// alwas returns the value of <paramref name="count"/>.
/// </returns>
public override int GetCharCount(byte[] bytes, int index, int count)
{
return count;
}
/// <summary>
/// Calculates the maximum number of bytes produced by encoding the specified number of characters.
/// </summary>
/// <returns>
/// The maximum number of bytes produced by encoding the specified number of characters. This
/// class alwas returns the value of <paramref name="charCount"/>.
/// </returns>
/// <param name="charCount">The number of characters to encode.
/// </param>
public override int GetMaxByteCount(int charCount)
{
return charCount;
}
/// <summary>
/// Calculates the maximum number of characters produced by decoding the specified number of bytes.
/// </summary>
/// <returns>
/// The maximum number of characters produced by decoding the specified number of bytes. This class
/// alwas returns the value of <paramref name="byteCount"/>.
/// </returns>
/// <param name="byteCount">The number of bytes to decode.</param>
public override int GetMaxCharCount(int byteCount)
{
return byteCount;
}
/// <summary>
/// Gets the number of characters that are supported by this encoding.
/// This property returns a maximum value of 256, as the encoding class
/// only supports single byte encodings (1 byte == 256 possible values).
/// </summary>
public static int CharacterCount
{
get { return byteToChar.Length; }
}
#region Character Table
/// <summary>
/// This table contains characters in an array. The index within the
/// array corresponds to the encoding's mapping of bytes to characters
/// (e.g. if a byte value of 5 is used to encode the character 'x', this
/// character will be stored at the array index 5.
/// </summary>
private static char[] byteToChar = new char[]
{
(char)0 /* byte 0 */ ,
(char)1 /* byte 1 */ ,
(char)2 /* byte 2 */ ,
(char)3 /* byte 3 */ ,
(char)4 /* byte 4 */ ,
(char)5 /* byte 5 */ ,
(char)6 /* byte 6 */ ,
(char)7 /* byte 7 */ ,
(char)8 /* byte 8 */ ,
(char)9 /* byte 9 */ ,
(char)10 /* byte 10 */ ,
(char)11 /* byte 11 */ ,
(char)12 /* byte 12 */ ,
(char)13 /* byte 13 */ ,
(char)14 /* byte 14 */ ,
(char)15 /* byte 15 */ ,
(char)16 /* byte 16 */ ,
(char)17 /* byte 17 */ ,
(char)18 /* byte 18 */ ,
(char)19 /* byte 19 */ ,
(char)20 /* byte 20 */ ,
(char)21 /* byte 21 */ ,
(char)22 /* byte 22 */ ,
(char)23 /* byte 23 */ ,
(char)24 /* byte 24 */ ,
(char)25 /* byte 25 */ ,
(char)26 /* byte 26 */ ,
(char)27 /* byte 27 */ ,
(char)28 /* byte 28 */ ,
(char)29 /* byte 29 */ ,
(char)30 /* byte 30 */ ,
(char)31 /* byte 31 */ ,
(char)32 /* byte 32 */ ,
(char)33 /* byte 33 */ ,
(char)34 /* byte 34 */ ,
(char)35 /* byte 35 */ ,
(char)36 /* byte 36 */ ,
(char)37 /* byte 37 */ ,
(char)38 /* byte 38 */ ,
(char)39 /* byte 39 */ ,
(char)40 /* byte 40 */ ,
(char)41 /* byte 41 */ ,
(char)42 /* byte 42 */ ,
(char)43 /* byte 43 */ ,
(char)44 /* byte 44 */ ,
(char)45 /* byte 45 */ ,
(char)46 /* byte 46 */ ,
(char)47 /* byte 47 */ ,
(char)48 /* byte 48 */ ,
(char)49 /* byte 49 */ ,
(char)50 /* byte 50 */ ,
(char)51 /* byte 51 */ ,
(char)52 /* byte 52 */ ,
(char)53 /* byte 53 */ ,
(char)54 /* byte 54 */ ,
(char)55 /* byte 55 */ ,
(char)56 /* byte 56 */ ,
(char)57 /* byte 57 */ ,
(char)58 /* byte 58 */ ,
(char)59 /* byte 59 */ ,
(char)60 /* byte 60 */ ,
(char)61 /* byte 61 */ ,
(char)62 /* byte 62 */ ,
(char)63 /* byte 63 */ ,
(char)64 /* byte 64 */ ,
(char)65 /* byte 65 */ ,
(char)66 /* byte 66 */ ,
(char)67 /* byte 67 */ ,
(char)68 /* byte 68 */ ,
(char)69 /* byte 69 */ ,
(char)70 /* byte 70 */ ,
(char)71 /* byte 71 */ ,
(char)72 /* byte 72 */ ,
(char)73 /* byte 73 */ ,
(char)74 /* byte 74 */ ,
(char)75 /* byte 75 */ ,
(char)76 /* byte 76 */ ,
(char)77 /* byte 77 */ ,
(char)78 /* byte 78 */ ,
(char)79 /* byte 79 */ ,
(char)80 /* byte 80 */ ,
(char)81 /* byte 81 */ ,
(char)82 /* byte 82 */ ,
(char)83 /* byte 83 */ ,
(char)84 /* byte 84 */ ,
(char)85 /* byte 85 */ ,
(char)86 /* byte 86 */ ,
(char)87 /* byte 87 */ ,
(char)88 /* byte 88 */ ,
(char)89 /* byte 89 */ ,
(char)90 /* byte 90 */ ,
(char)91 /* byte 91 */ ,
(char)92 /* byte 92 */ ,
(char)93 /* byte 93 */ ,
(char)94 /* byte 94 */ ,
(char)95 /* byte 95 */ ,
(char)96 /* byte 96 */ ,
(char)97 /* byte 97 */ ,
(char)98 /* byte 98 */ ,
(char)99 /* byte 99 */ ,
(char)100 /* byte 100 */ ,
(char)101 /* byte 101 */ ,
(char)102 /* byte 102 */ ,
(char)103 /* byte 103 */ ,
(char)104 /* byte 104 */ ,
(char)105 /* byte 105 */ ,
(char)106 /* byte 106 */ ,
(char)107 /* byte 107 */ ,
(char)108 /* byte 108 */ ,
(char)109 /* byte 109 */ ,
(char)110 /* byte 110 */ ,
(char)111 /* byte 111 */ ,
(char)112 /* byte 112 */ ,
(char)113 /* byte 113 */ ,
(char)114 /* byte 114 */ ,
(char)115 /* byte 115 */ ,
(char)116 /* byte 116 */ ,
(char)117 /* byte 117 */ ,
(char)118 /* byte 118 */ ,
(char)119 /* byte 119 */ ,
(char)120 /* byte 120 */ ,
(char)121 /* byte 121 */ ,
(char)122 /* byte 122 */ ,
(char)123 /* byte 123 */ ,
(char)124 /* byte 124 */ ,
(char)125 /* byte 125 */ ,
(char)126 /* byte 126 */ ,
(char)127 /* byte 127 */ ,
(char)128 /* byte 128 */ ,
(char)129 /* byte 129 */ ,
(char)130 /* byte 130 */ ,
(char)131 /* byte 131 */ ,
(char)132 /* byte 132 */ ,
(char)133 /* byte 133 */ ,
(char)134 /* byte 134 */ ,
(char)135 /* byte 135 */ ,
(char)136 /* byte 136 */ ,
(char)137 /* byte 137 */ ,
(char)138 /* byte 138 */ ,
(char)139 /* byte 139 */ ,
(char)140 /* byte 140 */ ,
(char)141 /* byte 141 */ ,
(char)142 /* byte 142 */ ,
(char)143 /* byte 143 */ ,
(char)144 /* byte 144 */ ,
(char)145 /* byte 145 */ ,
(char)146 /* byte 146 */ ,
(char)147 /* byte 147 */ ,
(char)148 /* byte 148 */ ,
(char)149 /* byte 149 */ ,
(char)150 /* byte 150 */ ,
(char)151 /* byte 151 */ ,
(char)152 /* byte 152 */ ,
(char)153 /* byte 153 */ ,
(char)154 /* byte 154 */ ,
(char)155 /* byte 155 */ ,
(char)156 /* byte 156 */ ,
(char)157 /* byte 157 */ ,
(char)158 /* byte 158 */ ,
(char)159 /* byte 159 */ ,
(char)160 /* byte 160 */ ,
(char)161 /* byte 161 */ ,
(char)162 /* byte 162 */ ,
(char)163 /* byte 163 */ ,
(char)164 /* byte 164 */ ,
(char)165 /* byte 165 */ ,
(char)166 /* byte 166 */ ,
(char)167 /* byte 167 */ ,
(char)168 /* byte 168 */ ,
(char)169 /* byte 169 */ ,
(char)170 /* byte 170 */ ,
(char)171 /* byte 171 */ ,
(char)172 /* byte 172 */ ,
(char)173 /* byte 173 */ ,
(char)174 /* byte 174 */ ,
(char)175 /* byte 175 */ ,
(char)176 /* byte 176 */ ,
(char)177 /* byte 177 */ ,
(char)178 /* byte 178 */ ,
(char)179 /* byte 179 */ ,
(char)180 /* byte 180 */ ,
(char)181 /* byte 181 */ ,
(char)182 /* byte 182 */ ,
(char)183 /* byte 183 */ ,
(char)184 /* byte 184 */ ,
(char)185 /* byte 185 */ ,
(char)186 /* byte 186 */ ,
(char)187 /* byte 187 */ ,
(char)188 /* byte 188 */ ,
(char)189 /* byte 189 */ ,
(char)190 /* byte 190 */ ,
(char)191 /* byte 191 */ ,
(char)192 /* byte 192 */ ,
(char)193 /* byte 193 */ ,
(char)194 /* byte 194 */ ,
(char)195 /* byte 195 */ ,
(char)196 /* byte 196 */ ,
(char)197 /* byte 197 */ ,
(char)198 /* byte 198 */ ,
(char)199 /* byte 199 */ ,
(char)200 /* byte 200 */ ,
(char)201 /* byte 201 */ ,
(char)202 /* byte 202 */ ,
(char)203 /* byte 203 */ ,
(char)204 /* byte 204 */ ,
(char)205 /* byte 205 */ ,
(char)206 /* byte 206 */ ,
(char)207 /* byte 207 */ ,
(char)208 /* byte 208 */ ,
(char)209 /* byte 209 */ ,
(char)210 /* byte 210 */ ,
(char)211 /* byte 211 */ ,
(char)212 /* byte 212 */ ,
(char)213 /* byte 213 */ ,
(char)214 /* byte 214 */ ,
(char)215 /* byte 215 */ ,
(char)216 /* byte 216 */ ,
(char)217 /* byte 217 */ ,
(char)218 /* byte 218 */ ,
(char)219 /* byte 219 */ ,
(char)220 /* byte 220 */ ,
(char)221 /* byte 221 */ ,
(char)222 /* byte 222 */ ,
(char)223 /* byte 223 */ ,
(char)224 /* byte 224 */ ,
(char)225 /* byte 225 */ ,
(char)226 /* byte 226 */ ,
(char)227 /* byte 227 */ ,
(char)228 /* byte 228 */ ,
(char)229 /* byte 229 */ ,
(char)230 /* byte 230 */ ,
(char)231 /* byte 231 */ ,
(char)232 /* byte 232 */ ,
(char)233 /* byte 233 */ ,
(char)234 /* byte 234 */ ,
(char)235 /* byte 235 */ ,
(char)236 /* byte 236 */ ,
(char)237 /* byte 237 */ ,
(char)238 /* byte 238 */ ,
(char)239 /* byte 239 */ ,
(char)240 /* byte 240 */ ,
(char)241 /* byte 241 */ ,
(char)242 /* byte 242 */ ,
(char)243 /* byte 243 */ ,
(char)244 /* byte 244 */ ,
(char)245 /* byte 245 */ ,
(char)246 /* byte 246 */ ,
(char)247 /* byte 247 */ ,
(char)248 /* byte 248 */ ,
(char)249 /* byte 249 */ ,
(char)250 /* byte 250 */ ,
(char)251 /* byte 251 */ ,
(char)252 /* byte 252 */ ,
(char)253 /* byte 253 */ ,
(char)254 /* byte 254 */ ,
(char)255 /* byte 255 */
};
#endregion
#region Byte Lookup Dictionary
/// <summary>
/// This dictionary is used to resolve byte values for a given character.
/// </summary>
private static Dictionary<char, byte> charToByte = new Dictionary<char, byte>
{
{ (char)0, 0 },
{ (char)1, 1 },
{ (char)2, 2 },
{ (char)3, 3 },
{ (char)4, 4 },
{ (char)5, 5 },
{ (char)6, 6 },
{ (char)7, 7 },
{ (char)8, 8 },
{ (char)9, 9 },
{ (char)10, 10 },
{ (char)11, 11 },
{ (char)12, 12 },
{ (char)13, 13 },
{ (char)14, 14 },
{ (char)15, 15 },
{ (char)16, 16 },
{ (char)17, 17 },
{ (char)18, 18 },
{ (char)19, 19 },
{ (char)20, 20 },
{ (char)21, 21 },
{ (char)22, 22 },
{ (char)23, 23 },
{ (char)24, 24 },
{ (char)25, 25 },
{ (char)26, 26 },
{ (char)27, 27 },
{ (char)28, 28 },
{ (char)29, 29 },
{ (char)30, 30 },
{ (char)31, 31 },
{ (char)32, 32 },
{ (char)33, 33 },
{ (char)34, 34 },
{ (char)35, 35 },
{ (char)36, 36 },
{ (char)37, 37 },
{ (char)38, 38 },
{ (char)39, 39 },
{ (char)40, 40 },
{ (char)41, 41 },
{ (char)42, 42 },
{ (char)43, 43 },
{ (char)44, 44 },
{ (char)45, 45 },
{ (char)46, 46 },
{ (char)47, 47 },
{ (char)48, 48 },
{ (char)49, 49 },
{ (char)50, 50 },
{ (char)51, 51 },
{ (char)52, 52 },
{ (char)53, 53 },
{ (char)54, 54 },
{ (char)55, 55 },
{ (char)56, 56 },
{ (char)57, 57 },
{ (char)58, 58 },
{ (char)59, 59 },
{ (char)60, 60 },
{ (char)61, 61 },
{ (char)62, 62 },
{ (char)63, 63 },
{ (char)64, 64 },
{ (char)65, 65 },
{ (char)66, 66 },
{ (char)67, 67 },
{ (char)68, 68 },
{ (char)69, 69 },
{ (char)70, 70 },
{ (char)71, 71 },
{ (char)72, 72 },
{ (char)73, 73 },
{ (char)74, 74 },
{ (char)75, 75 },
{ (char)76, 76 },
{ (char)77, 77 },
{ (char)78, 78 },
{ (char)79, 79 },
{ (char)80, 80 },
{ (char)81, 81 },
{ (char)82, 82 },
{ (char)83, 83 },
{ (char)84, 84 },
{ (char)85, 85 },
{ (char)86, 86 },
{ (char)87, 87 },
{ (char)88, 88 },
{ (char)89, 89 },
{ (char)90, 90 },
{ (char)91, 91 },
{ (char)92, 92 },
{ (char)93, 93 },
{ (char)94, 94 },
{ (char)95, 95 },
{ (char)96, 96 },
{ (char)97, 97 },
{ (char)98, 98 },
{ (char)99, 99 },
{ (char)100, 100 },
{ (char)101, 101 },
{ (char)102, 102 },
{ (char)103, 103 },
{ (char)104, 104 },
{ (char)105, 105 },
{ (char)106, 106 },
{ (char)107, 107 },
{ (char)108, 108 },
{ (char)109, 109 },
{ (char)110, 110 },
{ (char)111, 111 },
{ (char)112, 112 },
{ (char)113, 113 },
{ (char)114, 114 },
{ (char)115, 115 },
{ (char)116, 116 },
{ (char)117, 117 },
{ (char)118, 118 },
{ (char)119, 119 },
{ (char)120, 120 },
{ (char)121, 121 },
{ (char)122, 122 },
{ (char)123, 123 },
{ (char)124, 124 },
{ (char)125, 125 },
{ (char)126, 126 },
{ (char)127, 127 },
{ (char)128, 128 },
{ (char)129, 129 },
{ (char)130, 130 },
{ (char)131, 131 },
{ (char)132, 132 },
{ (char)133, 133 },
{ (char)134, 134 },
{ (char)135, 135 },
{ (char)136, 136 },
{ (char)137, 137 },
{ (char)138, 138 },
{ (char)139, 139 },
{ (char)140, 140 },
{ (char)141, 141 },
{ (char)142, 142 },
{ (char)143, 143 },
{ (char)144, 144 },
{ (char)145, 145 },
{ (char)146, 146 },
{ (char)147, 147 },
{ (char)148, 148 },
{ (char)149, 149 },
{ (char)150, 150 },
{ (char)151, 151 },
{ (char)152, 152 },
{ (char)153, 153 },
{ (char)154, 154 },
{ (char)155, 155 },
{ (char)156, 156 },
{ (char)157, 157 },
{ (char)158, 158 },
{ (char)159, 159 },
{ (char)160, 160 },
{ (char)161, 161 },
{ (char)162, 162 },
{ (char)163, 163 },
{ (char)164, 164 },
{ (char)165, 165 },
{ (char)166, 166 },
{ (char)167, 167 },
{ (char)168, 168 },
{ (char)169, 169 },
{ (char)170, 170 },
{ (char)171, 171 },
{ (char)172, 172 },
{ (char)173, 173 },
{ (char)174, 174 },
{ (char)175, 175 },
{ (char)176, 176 },
{ (char)177, 177 },
{ (char)178, 178 },
{ (char)179, 179 },
{ (char)180, 180 },
{ (char)181, 181 },
{ (char)182, 182 },
{ (char)183, 183 },
{ (char)184, 184 },
{ (char)185, 185 },
{ (char)186, 186 },
{ (char)187, 187 },
{ (char)188, 188 },
{ (char)189, 189 },
{ (char)190, 190 },
{ (char)191, 191 },
{ (char)192, 192 },
{ (char)193, 193 },
{ (char)194, 194 },
{ (char)195, 195 },
{ (char)196, 196 },
{ (char)197, 197 },
{ (char)198, 198 },
{ (char)199, 199 },
{ (char)200, 200 },
{ (char)201, 201 },
{ (char)202, 202 },
{ (char)203, 203 },
{ (char)204, 204 },
{ (char)205, 205 },
{ (char)206, 206 },
{ (char)207, 207 },
{ (char)208, 208 },
{ (char)209, 209 },
{ (char)210, 210 },
{ (char)211, 211 },
{ (char)212, 212 },
{ (char)213, 213 },
{ (char)214, 214 },
{ (char)215, 215 },
{ (char)216, 216 },
{ (char)217, 217 },
{ (char)218, 218 },
{ (char)219, 219 },
{ (char)220, 220 },
{ (char)221, 221 },
{ (char)222, 222 },
{ (char)223, 223 },
{ (char)224, 224 },
{ (char)225, 225 },
{ (char)226, 226 },
{ (char)227, 227 },
{ (char)228, 228 },
{ (char)229, 229 },
{ (char)230, 230 },
{ (char)231, 231 },
{ (char)232, 232 },
{ (char)233, 233 },
{ (char)234, 234 },
{ (char)235, 235 },
{ (char)236, 236 },
{ (char)237, 237 },
{ (char)238, 238 },
{ (char)239, 239 },
{ (char)240, 240 },
{ (char)241, 241 },
{ (char)242, 242 },
{ (char)243, 243 },
{ (char)244, 244 },
{ (char)245, 245 },
{ (char)246, 246 },
{ (char)247, 247 },
{ (char)248, 248 },
{ (char)249, 249 },
{ (char)250, 250 },
{ (char)251, 251 },
{ (char)252, 252 },
{ (char)253, 253 },
{ (char)254, 254 },
{ (char)255, 255 }
};
#endregion
}

Related

undefined error with calling ble_gatts_count_cfg function

I am programing my esp32 to be able to advertise my custom services/characteristics. I am failry new to esp idf and I am struggling to program bluetooth using nimBLE. during building,there is no error thrown but while monitoring, i receive the following error from the function in main:
I (391) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (397) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (403) heap_init: At 3FFC49F0 len 0001B610 (109 KiB): DRAM
I (409) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (415) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (422) heap_init: At 40096DB0 len 00009250 (36 KiB): IRAM
I (429) spi_flash: detected chip: generic
I (433) spi_flash: flash io: dio
I (438) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (484) BTDM_INIT: BT controller compile version [1342a48]
I (484) system_api: Base MAC address is not set
I (484) system_api: read default base MAC address from EFUSE
I (494) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
ESP_ERROR_CHECK failed: esp_err_t 0x3 (ERROR) at 0x4008e6f4
0x4008e6f4: _esp_error_check_failed at C:/Users/Kanimba/Desktop/esp-idf/components/esp_common/src/esp_err.c:41
file: "../main/main.c" line 35
func: app_main
expression: gatt_svrs_init()
abort() was called at PC 0x4008e6f7 on core 0
0x4008e6f7: _esp_error_check_failed at C:/Users/Kanimba/Desktop/esp-idf/components/esp_common/src/esp_err.c:42
Backtrace:0x4008f64b:0x3ffbc340 0x4008fe1d:0x3ffbc360 0x400951f2:0x3ffbc380 0x4008e6f7:0x3ffbc3f0 0x400d5a86:0x3ffbc410 0x401205ed:0x3ffbc430 0x40092e45:0x3ffbc450
0x4008f64b: panic_abort at C:/Users/Kanimba/Desktop/esp-idf/components/esp_system/panic.c:356
0x4008fe1d: esp_system_abort at C:/Users/Kanimba/Desktop/esp-idf/components/esp_system/system_api.c:112
0x400951f2: abort at C:/Users/Kanimba/Desktop/esp-idf/components/newlib/abort.c:46
0x4008e6f7: _esp_error_check_failed at C:/Users/Kanimba/Desktop/esp-idf/components/esp_common/src/esp_err.c:42
0x400d5a86: app_main at C:\Users\Kanimba\Desktop\work_project\esp\embedded-test-ble\build/../main/main.c:35 (discriminator 1)
0x401205ed: main_task at C:/Users/Kanimba/Desktop/esp-idf/components/freertos/port/port_common.c:133 (discriminator 2)
0x40092e45: vPortTaskWrapper at C:/Users/Kanimba/Desktop/esp-idf/components/freertos/port/xtensa/port.c:168
whereby gatt_svrs_init() is called to initializes the following;
int gatt_svrs_init(void) {
int rc;
ble_svc_gap_init();
ble_svc_gatt_init();
rc = ble_gatts_count_cfg(gatt_svsc);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(gatt_svsc);
if (rc != 0) {
return rc;
}
return 0;
}
my main,c file looks like this
#include "config.h"
#include "gatt_svr.h"
#include "esp_log.h"
#include "esp_nimble_hci.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
void app_main() {
int rc;
/* initalise non-valatile storage NVS*/
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
/* initialise nimble */
ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init());
/* initialise apache port to nimble */
nimble_port_init();
/*Initialize the NimBLE host configuration */
ble_hs_cfg.reset_cb = ble_on_reset;
ble_hs_cfg.sync_cb = ble_on_sync;
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
ble_hs_cfg.store_status_cb =
ble_store_util_status_rr; // said to not be useful, need to do more,
ESP_ERROR_CHECK(gatt_svrs_init());
// assert(rc == 0);
/*set the default device name*/
ESP_ERROR_CHECK(ble_svc_gap_device_name_set(DEVICE_NAME));
// storing configuration "quite not sure how this function works"
ble_store_config_init();
nimble_port_freertos_init(host_task);
}
and the structure of the service:
static const struct ble_gatt_svc_def gatt_svsc[] = {
{/* Device info service/ SIG */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(DEVICE_INFO_SERVICE),
.characteristics =
(struct ble_gatt_chr_def[]){
{/* manufacturer name characteristic */
.uuid = BLE_UUID16_DECLARE(MANUFACTURER_NAME),
.flags = BLE_GATT_CHR_F_READ,
.access_cb = gatt_svr_access_device_info},
{/*serial number characteristic */
.uuid = BLE_UUID16_DECLARE(DEVICE_SERIAL_NUMBER),
.flags = BLE_GATT_CHR_F_READ,
.access_cb = gatt_svr_access_device_info},
{/*software version characteristic */
.uuid = BLE_UUID16_DECLARE(SOFTWARE_VERSION),
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
.access_cb = gatt_svr_access_device_info},
{0}}},
{.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &DEVICE_STATE_SERVICE.u,
.characteristics =
(struct ble_gatt_chr_def[]){{
/* manufacturer name characteristic
*/
.uuid = &CURRENT_SPECTRUM.u,
.flags = BLE_GATT_CHR_F_READ,
},
{
/* manufacturer name characteristic
*/
.uuid = &DEVICE_TEMPERATURE.u,
.flags = BLE_GATT_CHR_F_READ,
},
{
/* manufacturer name characteristic
*/
.uuid = &CURRENT_INTESITY.u,
.flags = BLE_GATT_CHR_F_READ,
},
{0}}},
{.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &MANUAL_SERVICE.u,
.characteristics =
(struct ble_gatt_chr_def[]){{
/* manula spectrum characteristic */
.uuid = &MANUAL_SPECTRUM.u,
.flags = BLE_GATT_CHR_F_READ,
},
{
/* light intensity characteristic */
.uuid = &LIGHT_INTESITY.u,
.flags = BLE_GATT_CHR_F_READ,
},
{
/* manual power characteristic */
.uuid = &MANUAL_POWER.u,
.flags = BLE_GATT_CHR_F_READ,
},
{0}}},
{.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &SCHEDULER_SERVICE.u,
.characteristics =
(struct ble_gatt_chr_def[]){{
/* Start_stage characteristic */
.uuid = &STAGE_START.u,
.flags = BLE_GATT_CHR_F_WRITE,
},
{
/* start day hours characteristic */
.uuid = &DAY_START_HOURS.u,
.flags = BLE_GATT_CHR_F_WRITE,
},
{
/* manufacturer name characteristic
*/
.uuid = &DAY_END_HOURS.u,
.flags = BLE_GATT_CHR_F_WRITE,
},
{
/* Light intensity characteristic */
.uuid = &LIGHT_INTESITY.u,
.flags = BLE_GATT_CHR_F_WRITE,
},
{0}}},
{0}};
I think there should be a access_cb associated for a characteristic which has a read or write flag . Can you try adding a access_cb to the characteristic with UUID SCHEDULER_SERVICE , MANUAL_SERVICE and DEVICE_STATE_SERVICE to see if it helps.

Python C API, override the PyNumberMethods nb_add field also changes the field in tp_base

I develop a new type: PyAlignArray_Type which derived from PyArray_Type
PyAlignArray_Type.tp_base = &PyArray_Type;
I override the nb_add field of tp_as_number as follow:
PyAlignArray_Type.tp_as_number->nb_add = (binaryfunc)ndarray_add ;
This works fine, but the field is also changed for base type (PyArray_Type).
My question is: How to overriding a PyNumberMethods field without changing it in the base type ?
typedef struct {
PyArrayObject array;
int pitch;
size_t size;
} PyAlignArrayObject;
/*---------------PyAlignArray_Type------------------*/
static PyTypeObject PyAlignArray_Type = {
PyObject_HEAD_INIT(NULL)
"plibs_8.ndarray", /* tp_name */
sizeof(PyAlignArrayObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)array_dealloc,/* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
ndarray_methods, /* tp_methods */
ndarray_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)ndarray_new, /* tp_new */
};
static PyModuleDef ndarraymodule = {
PyModuleDef_HEAD_INIT,
"ndarray",
"ndarray module",
-1,
NULL, NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC
PyInit_ndarray(void)
{
PyObject *m;
import_array();
PyAlignArray_Type.tp_base = &PyArray_Type;
if (PyType_Ready(&PyAlignArray_Type) < 0)
return NULL;
// __add__ overloading
PyAlignArray_Type.tp_as_number->nb_add = (binaryfunc)ndarray_add ;
m = PyModule_Create(&ndarraymodule);
if (m == NULL)
return NULL;
Py_INCREF(&PyAlignArray_Type);
PyModule_AddObject(m, "ndarray", (PyObject *) &PyAlignArray_Type);
return m;
}
I think you're right - this is odd, non-intuitive behaviour. It is fixable though. The documentation says
The tp_as_number field is not inherited, but the contained fields are inherited individually.
which implies that it should be OK to override them as you've done. What it actually seems to mean is:
The tp_as_number field is not inherited, but the contained fields are inherited individually if you provide space for them. If you don't provide space for them then the tp_as_number field is set to point at the base classes tp_as_number field.
(Italics are my addition. See code at https://github.com/python/cpython/blob/3e8d6cb1892377394e4b11819c33fbac728ea9e0/Objects/typeobject.c#L5111 and https://github.com/python/cpython/blob/3e8d6cb1892377394e4b11819c33fbac728ea9e0/Objects/typeobject.c#L4757). This means that, as in your example, you're also changing the base class methods.
The solution to this is to create a zero initialized PyNumberMethods and reference that in your class
static PyNumberMethods align_array_number_methods = { NULL };
/* You could also specify the nb_add field here and you wouldn't
have to do it in your module init */
static PyTypeObject PyAlignArray_Type = {
/* whole bunch of code unchanged */
&align_array_number_methods, /* tp_as_number */
/* whole bunch of code unchanged */
The slots you left as NULL are filled in according to the inheritance rules in PyType_Ready
I think the reason for this odd behaviour is to avoid introducing memory leaks. When you call PyType_Ready (which is where the inheritance is dealt with) it can't allocate PyNumberMethods statically so it would have to to malloc it. Since you don't know whether it's malloced these fields or not the memory that never get freed. (This is only a concern for dynamically created types).

passing arguments to drivers probe function

In the call chain of module_i2c_driver() i am not able to find that where arguments are passed to the function adxl34x_i2c_probe().
static int adxl34x_i2c_probe(struct i2c_client *client,
78 const struct i2c_device_id *id)
79 {
...
99 return 0;
100 }
158 static struct i2c_driver adxl34x_driver = {
159 .driver = {
160 .name = "adxl34x",
161 .owner = THIS_MODULE,
162 .pm = &adxl34x_i2c_pm,
163 .of_match_table = of_match_ptr(adxl34x_of_id),
164 },
165 .probe = adxl34x_i2c_probe,
166 .remove = adxl34x_i2c_remove,
167 .id_table = adxl34x_id,
168 };
169
170 module_i2c_driver(adxl34x_driver);
i2c_driver's probe callback is called from i2c_device_probe function (http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L632).
With
.probe = adxl34x_i2c_probe
you're setting callback function pointer of probe to point to adx134x_i2c_probe, so calling driver->probe (http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L672) with passed arguments is actually calling adxl34x_i2c_probe with the same arguments.

Chipsee 7 inch LCD support in Linux kernel 3.14

Has anybody ported Chipsee 7 inch LCD on Linux kernel 3.14 or later ?
Is there any patch available for the same ?
If no patches any suggestion porting Chipsee LCD support from Linux kernel 3.8 to Linux kernel 3.14 ?
Update:
`/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
#include "am33xx.dtsi"
#include "am335x-bone-common.dtsi"
&ldo3_reg {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
/*
&mmc1 {
vmmc-supply = <&vmmcsd_fixed>;
};
&mmc2 {
vmmc-supply = <&vmmcsd_fixed>;
pinctrl-names = "default";
pinctrl-0 = <&emmc_pins>;
bus-width = <8>;
status = "okay";
ti,vcc-aux-disable-is-sleep;
};
*/
&am33xx_pinmux {
userled_pins: pinmux_userled_pins {
pinctrl-single,pins = <
0x98 0x7 /* gpmc_wen.gpio2_4, OUTPUT | MODE7 */
0x9c 0x7 /* gpmc_ben0_cle.gpio2_5, OUTPUT | MODE7 */
>;
};
i2c0_pins: pinmux_i2c0_pins {
pinctrl-single,pins = <
0x188 0x70 /* i2c0_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */
0x18c 0x70 /* i2c0_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */
>;
};
i2c1_pins: pinmux_i2c1_pins {
pinctrl-single,pins = <
0x158 0x72 /* spi0_d1.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
0x15c 0x72 /* spi0_cs0.i2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
>;
};
mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
0x160 0x2f /* GPIO0_6 (PIN_INPUT | MUX_MODE7) */
>;
};
rstctl_pins: pinmux_rstctl_pins {
pinctrl-single,pins = <
/* eMMC_RSTn */
0x50 0x17 /* gpmc_a4.gpio1_20, OUTPUT | MODE7 | PULLUP */
>;
};
chipsee_lcd_pins: pinmux_chipsee_lcd_pins {
pinctrl-single,pins = <
0xa0 0x00 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xa4 0x00 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xa8 0x00 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xac 0x00 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xb0 0x00 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xb4 0x00 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xb8 0x00 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xbc 0x00 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xc0 0x00 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xc4 0x00 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xc8 0x00 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xcc 0x00 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xd0 0x00 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xd4 0x00 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xd8 0x00 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xdc 0x00 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0x3c 0x11 /* gpmc_ad15.lcd_data16, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x38 0x11 /* gpmc_ad14.lcd_data17, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x34 0x11 /* gpmc_ad13.lcd_data18, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x30 0x11 /* gpmc_ad12.lcd_data19, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x2c 0x11 /* gpmc_ad11.lcd_data20, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x28 0x11 /* gpmc_ad10.lcd_data21, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x24 0x11 /* gpmc_ad9.lcd_data22, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0x20 0x11 /* gpmc_ad8.lcd_data23, OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT */
0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
>;
};
pwm_bl_pins: pinmux_pwm_bl_pins {
pinctrl-single,pins = <
0x48 0x06 /* gpmc_a2.ehrpwm1a, OMAP_MUX_MODE6 | AM33XX_PIN_OUTPUT */
>;
};
chipsee_gpio_pins: pinmux_chipsee_gpio_pins {
pinctrl-single,pins = <
0x044 0x27 /* CAP_TSC gpmc_a1.gpio1_17, INPUT | MODE7 */
0x094 0x07 /* BUZZER gpmc_oen_ren.gpio2_3 OUTPUT | MODE7 */
>;
};
chipsee_gpio_keys_pins: pinmux_chipsee_gpio_keys_pins {
pinctrl-single,pins = <
0x164 0x2f /* KEY_LEFT ecap0_in_pwm0_out.gpio0_7, INPUT | PULLDIS | MODE7 */
0x078 0x2f /* KEY_RIGHT gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
0x040 0x2f /* KEY_UP gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
0x04c 0x2f /* KEY_DOWN gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
0x1a4 0x2f /* KEY_ENTER mcasp0_fxr.gpio3_19, INPUT | PULLDIS | MODE7 */
>;
};
chipsee_uart1_pins: pinmux_chipsee_uart1_pins {
pinctrl-single,pins = <
0x180 0x20 /* uart1_rxd.uart1_rxd INPUT | MODE0 */
0x184 0x00 /* uart1_txd.uart1_txd OUTPUT | MODE0 */
>;
};
chipsee_uart2_pins: pinmux_chipsee_uart2_pins {
pinctrl-single,pins = <
0x150 0x21 /* spi0_sclk.uart2_rxd INPUT | MODE1 */
0x154 0x01 /* spi0_d0.uart2_txd OUTPUT | MODE1 */
>;
};
chipsee_uart4_pins: pinmux_chipsee_uart4_pins {
pinctrl-single,pins = <
0x070 0x26 /* gpmc_wait0.uart4_rxd INPUT | MODE6 */
0x074 0x06 /* gpmc_wpn.uart4_txd OUTPUT | MODE6 */
>;
};
chipsee_dcan0_pins: pinmux_chipsee_dcan0_pins {
pinctrl-single,pins = <
0x178 0x02 /* uart1_ctsn.d_can0_tx OUTPUT | MODE2 */
0x17c 0x32 /* uart1_rtsn.d_can0_rx INPUT_PULLUP | MODE2 */
>;
};
chipsee_audio_pins: pinmux_chipsee_audio_pins {
pinctrl-single,pins = <
0x190 0x20 /* mcasp0_aclkx.mcasp0_aclkx, INPUT | MODE0 */
0x194 0x20 /* mcasp0_fsx.mcasp0_fsx, INPUT | MODE0 */
0x198 0x20 /* mcasp0_axr0.mcasp0_axr0, INPUT | MODE0 */
0x19c 0x22 /* mcasp0_ahclkr.mcasp0_axr2, INPUT | MODE2 */
>;
};
};
/*
* To consider voltage drop between PMIC and SoC,
* tolerance value is reduced to 2% from 4% and
* voltage value is increased as a precaution.
*/
/* kHz uV */
/*
&cpus {
&cpu#0 {
operating-points = <
1000000 1350000
800000 1300000
600000 1112000
300000 969000
>;
};
};
*/
/{
ocp {
uartt0:serial#44e09000 {
status = "okay";
};
/*
epwmss1: epwmss#48302000 {
status = "okay";
ehrpwm1: ehrpwm#48302200 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pwm_bl_pins>;
};
};
*/
/* backlight {
compatible = "pwm-backlight";
pwms = <&ehrpwm1 0 500000 0>;
brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
default-brightness-level = <101>;
};
index to the array above
*/
gpio-leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&userled_pins>;
led0 {
label = "beaglebone:green:usr0";
gpios = <&gpio3 4 0>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
led1 {
label = "beaglebone:green:usr1";
gpios = <&gpio3 5 0>;
linux,default-trigger = "mmc0";
default-state = "off";
};
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_gpio_keys_pins>;
#address-cells = <1>;
#size-cells = <0>;
button#1 {
debounce_interval = <50>;
linux,code = <105>;
label = "left";
gpios = <&gpio1 7 0x1>;
gpio-key,wakeup;
autorepeat;
};
button#2 {
debounce_interval = <50>;
linux,code = <106>;
label = "right";
gpios = <&gpio2 28 0x1>;
gpio-key,wakeup;
autorepeat;
};
button#3 {
debounce_interval = <50>;
linux,code = <103>;
label = "up";
gpios = <&gpio2 16 0x1>;
gpio-key,wakeup;
autorepeat;
};
button#4 {
debounce_interval = <50>;
linux,code = <108>;
label = "down";
gpios = <&gpio2 19 0x1>;
gpio-key,wakeup;
autorepeat;
};
button#5 {
debounce_interval = <50>;
linux,code = <28>;
label = "enter";
gpios = <&gpio3 19 0x1>;
gpio-key,wakeup;
};
};
gpio_setups {
compatible = "gpio-of-helper";
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_gpio_pins>;
/* declare your gpios */
cap_touch_int {
gpio-name = "cap_touch_int";
gpio = <&gpio2 17 0x00>;
input;
};
buzzer {
gpio-name = "buzzer";
gpio = <&gpio3 3 0x00>;
output;
init-low;
};
};
rtc#44e3e000 {
ti,system-power-controller;
status = "okay";
};
panel {
compatible = "tilcdc,panel";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_lcd_pins>;
panel-info {
ac-bias = <255>;
ac-bias-intrpt = <0>;
dma-burst-sz = <16>;
bpp = <32>;
fdd = <0x80>;
tft-alt-mode = <0>;
stn-565-mode = <0>;
mono-8bit-mode = <0>;
sync-edge = <0>;
sync-ctrl = <0>;
raster-order = <1>;
fifo-th = <0>;
};
display-timings {
native-mode = <&timing0>;
timing0: 1024x600 {
hactive = <1024>;
vactive = <600>;
hback-porch = <45>;
hfront-porch = <1>;
hsync-len = <30>;
vback-porch = <22>;
vfront-porch = <12>;
vsync-len = <2>;
clock-frequency = <36000000>;
hsync-active = <1>;
vsync-active = <1>;
};
};
};
fb {
compatible = "ti,am33xx-tilcdc";
reg = <0x4830e000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <36>;
ti,hwmods = "lcdc";
ti,allow-non-reduced-blanking-modes;
};
tscadc {
compatible = "ti,ti-tscadc";
reg = <0x44e0d000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <16>;
ti,hwmods = "adc_tsc";
status = "okay";
tsc {
ti,wires = <4>;
ti,x-plate-resistance = <200>;
ti,steps-to-config= <5>;
ti,x-min= <0xCB>;
ti,x-max= <0xFFF>;
ti,x-inverted= <0>;
ti,y-min= <0xC8>;
ti,y-max= <0xFFF>;
ti,y-inverted= <0>;
};
adc {
ti,adc-channels = <4 5 6 7>;
};
};
sound {
compatible = "ti,da830-evm-audio";
ti,model = "DA830 EVM";
ti,audio-codec = <&tlv320aic3x>;
ti,mcasp-controller = <&mcasp0>;
ti,codec-clock-rate = <12000000>;
ti,audio-routing =
"Headphone Jack", "HPLOUT",
"Headphone Jack", "HPROUT",
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack";
};
};
};
&mcasp0 {
pinctrl-names = "default";
pinctrl-0 = <&chipsee_audio_pins>;
status = "okay";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
num-serializer = <16>;
serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
1 0 2 0
0 0 0 0
0 0 0 0
0 0 0 0
>;
tx-num-evt = <1>;
rx-num-evt = <1>;
};
&i2c0 {
status = "okay";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins>;
tps: tps#24 {
reg = <0x24>;
};
baseboard_eeprom: baseboard_eeprom#50 {
compatible = "at,24c256";
reg = <0x50>;
};
};
&i2c1 {
status = "okay";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
ft5x06_ts: ft5x06_ts#38 {
compatible = "ft5x06_ts";
reg = <0x38>;
interrupt-parent = <&gpio2>;
interrupts = <17>;
};
tlv320aic3x: tlv320aic3x#1b {
compatible = "ti,tlv320aic3x";
reg = <0x1b>;
status = "okay";
};
};
#include "tps65217.dtsi"
&tps {
ti,pmic-shutdown-controller;
interrupt-parent = <&intc>;
interrupts = <7>; /* NNMI */
regulators {
dcdc1_reg: regulator#0 {
regulator-always-on;
};
dcdc2_reg: regulator#1 {
/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
regulator-name = "vdd_mpu";
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <1325000>;
regulator-boot-on;
regulator-always-on;
};
dcdc3_reg: regulator#2 {
/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
regulator-name = "vdd_core";
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <1150000>;
regulator-boot-on;
regulator-always-on;
};
ldo1_reg: regulator#3 {
regulator-always-on;
};
ldo2_reg: regulator#4 {
regulator-always-on;
};
ldo3_reg: regulator#5 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
ldo4_reg: regulator#6 {
regulator-always-on;
};
};
};
&uart1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_uart1_pins>;
};
&uart2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_uart2_pins>;
};
&uart4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_uart4_pins>;
};
&dcan0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&chipsee_dcan0_pins>;
};
&cpsw_emac0 {
phy_id = <&davinci_mdio>, <0>;
};
&cpsw_emac1 {
phy_id = <&davinci_mdio>, <1>;
};
&mmc1 {
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
bus-width = <0x4>;
cd-gpios = <&gpio1 6 0>; /* gpio1 is misnamed, 0 == GPIO_ACTIVE_HIGH */
cd-inverted;
status = "okay";
vmmc-supply = <&ldo3_reg>;
ti,vcc-aux-disable-is-sleep;
};
&edma {
ti,edma-xbar-event-map = <32 12>, /* gpevt2 -> 12 */
<30 20>; /* xdma_event_intr2 -> 20 */
};
&sham {
status = "okay";
};
&aes {
status = "okay";
};
&usb {
interface_type = <1>;
power = <250>;
status = "okay";
};
&ldo3_reg {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
/*
rstctl {
status = "okay";
compatible = "gpio-rctrl";
pinctrl-names = "default";
pinctrl-0 = <&rstctl_pins>;
#reset-cells = <2>;
gpios = <&gpio2 20 0x00>;
gpio-names = "eMMC_RSTn";
};
*/
&mmc1 {
vmmc-supply = <&vmmcsd_fixed>;
};
/*
&mmc2 {
vmmc-supply = <&vmmcsd_fixed>;
bus-width = <8>;
ti,non-removable;
status = "disabled";
reset = <&rstctl 0 0>;
reset-names = "eMMC_RSTn-CONSUMER";
};
*/
`
After changing devicetree as above, i get following output,
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
hw perfevents: enabled with ARMv7 Cortex-A8 PMU driver, 5 counters available
futex hash table entries: 256 (order: -1, 3072 bytes)
NFS: Registering the id_resolver key type
Key type id_resolver registered
Key type id_legacy registered
msgmni has been set to 987
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568
omap_uart 44e09000.serial: no wakeirq for uart0
44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud = 3000000) is a O MAP UART0
omap_uart 48022000.serial: no wakeirq for uart0
48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89, base_baud = 3000000) is a O MAP UART1
console [ttyO1] enabled
omap_uart 48024000.serial: no wakeirq for uart0
48024000.serial: ttyO2 at MMIO 0x48024000 (irq = 90, base_baud = 3000000) is a O MAP UART2
omap_uart 481a8000.serial: no wakeirq for uart0
481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61, base_baud = 3000000) is a O MAP UART4
[drm] Initialized drm 1.1.0 20060810
brd: module loaded
mtdoops: mtd device (mtddev=name/number) must be supplied
usbcore: registered new interface driver kaweth
pegasus: v0.9.3 (2013/04/25), Pegasus/Pegasus II USB Ethernet driver
usbcore: registered new interface driver pegasus
usbcore: registered new interface driver rtl8150
usbcore: registered new interface driver asix
usbcore: registered new interface driver ax88179_178a
usbcore: registered new interface driver cdc_ether
usbcore: registered new interface driver dm9601
usbcore: registered new interface driver smsc75xx
usbcore: registered new interface driver smsc95xx
usbcore: registered new interface driver net1080
usbcore: registered new interface driver cdc_subset
usbcore: registered new interface driver zaurus
usbcore: registered new interface driver MOSCHIP usb-ethernet driver
usbcore: registered new interface driver int51x1
usbcore: registered new interface driver cdc_ncm
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-omap: OMAP-EHCI Host Controller driver
usbcore: registered new interface driver usb-storage
mousedev: PS/2 mouse device common for all mice
omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
i2c /dev entries driver
omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
48060000.mmc supply vmmc_aux not found, using dummy regulator
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
oprofile: using arm/armv7
u32 classifier
Actions configured
TCP: cubic registered
NET: Registered protocol family 10
sit: IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
Key type dns_resolver registered
ThumbEE CPU extension supported.
bio: create slab <bio-1> at 1
Btrfs loaded
vmmcsd_fixed: disabling
regulator-dummy: disabling
tilcdc 4830e000.fb: no encoders/connectors found
tilcdc 4830e000.fb: failed to initialize mode setting
DCDC1: at 1500 mV
vdd_mpu: 925 <--> 1325 mV at 1100 mV
vdd_core: 925 <--> 1150 mV at 1100 mV
LDO1: at 1800 mV
LDO2: at 3300 mV
LDO3: 1800 mV
LDO4: at 3300 mV
tps65217 0-0024: TPS65217 ID 0xe version 1.2
omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz
omap_i2c 4802a000.i2c: bus 1 rev0.11 at 400 kHz
console [netcon0] enabled
netconsole: network logging started
davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
davinci_mdio 4a101000.mdio: detected phy mask fffffffe
libphy: 4a101000.mdio: probed
davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver SMSC LAN8710 /LAN8720
Detected MACID = 90:59:af:5b:ec:e5
input: gpio_keys.5 as /devices/ocp.3/gpio_keys.5/input/input0
omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 00:00:00 UTC (94668480 0)
VFS: Cannot open root device "mmcblk0p2" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
VFS: Unable to mount root fs on unknown-block(0,0)
User configuration error - no valid root filesystem found
Kernel panic - not syncing: Invalid configuration from end user prevents continu ing
CPU: 0 PID: 1 Comm: swapper Not tainted 3.14.0-yocto-standard #1
[<c0014fa8>] (unwind_backtrace) from [<c00123d8>] (show_stack+0x20/0x24)
[<c00123d8>] (show_stack) from [<c06b8bc4>] (dump_stack+0x20/0x28)
[<c06b8bc4>] (dump_stack) from [<c06b48f8>] (panic+0x8c/0x1c8)
[<c06b48f8>] (panic) from [<c09c1194>] (mount_block_root+0x1fc/0x244)
[<c09c1194>] (mount_block_root) from [<c09c13ac>] (mount_root+0xe8/0x10c)
[<c09c13ac>] (mount_root) from [<c09c1534>] (prepare_namespace+0x164/0x1c4)
[<c09c1534>] (prepare_namespace) from [<c09c0d4c>] (kernel_init_freeable+0x228/0 x278)
[<c09c0d4c>] (kernel_init_freeable) from [<c06b3c54>] (kernel_init+0x1c/0xf4)
[<c06b3c54>] (kernel_init) from [<c000e338>] (ret_from_fork+0x14/0x20)
¦¦¦¦¦¦¦¦¦¦¦

Windows WriteFile and ReadFile interferes with each other

I have two threads, one calls WriteFile, the other calls ReadFile, both uses the same serial port at 115200. What I have found repeatedly is that when I add more sequential WriteFile calls in the writing thread, is that I have an increased number of check-sum failures i.e. corrupt data. If I add delays between the WriteFile calls in the writing thread (using CBaseDLIMessage::CrossSleep(20) ), the check-sum errors reduce or even completely go away (depending on the sleep time), however the problem comes back when adding additional WriteFile methods.
Is it possible that the WriteFile method can somehow write data into a shared buffer, which is also used for reading (at driver level), which subsequently corrupts my read data?
My serial setup code looks like this:
CommHandle OpenSerialPort(int nId, long baud)
{
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
char szCOM[16];
/* COM waiting */
COMMTIMEOUTS g_cto =
{
MAXDWORD, /* ReadIntervalTimeOut */
0, /* ReadTotalTimeOutMultiplier */
0, /* ReadTotalTimeOutConstant */
0, /* WriteTotalTimeOutMultiplier */
0 /* WriteTotalTimeOutConstant */
};
/* COM configuration */
DCB g_dcb =
{
sizeof(DCB), /* DCBlength */
baud, /* BaudRate */
TRUE, /* fBinary */
FALSE, /* fParity */
FALSE, /* fOutxCtsFlow */
FALSE, /* fOutxDsrFlow */
DTR_CONTROL_DISABLE, /* fDtrControl */
FALSE, /* fDsrSensitivity */
FALSE, /* fTXContinueOnXoff */
FALSE, /* fOutX */
FALSE, /* fInX */
FALSE, /* fErrorChar */
FALSE, /* fNull */
RTS_CONTROL_DISABLE, /* fRtsControl */
FALSE, /* fAbortOnError */
0, /* fDummy2 */
0, /* wReserved */
0x100, /* XonLim */
0x100, /* XoffLim */
8, /* ByteSize */
NOPARITY, /* Parity */
ONESTOPBIT, /* StopBits */
0x11, /* XonChar */
0x13, /* XoffChar */
'?', /* ErrorChar */
0x1A, /* EofChar */
0x10 /* EvtChar */
};
//cout << "COM:::" << nId;
sprintf(szCOM, "\\\\.\\COM%d", nId);
HANDLE hCOM = CreateFile(szCOM, /* lpFileName */
GENERIC_READ|GENERIC_WRITE, /* dwDesiredAccess */
0, /* dwShareMode */
NULL, /* lpSecurityAttributes */
OPEN_EXISTING, /* dwCreationDisposition */
FILE_ATTRIBUTE_SYSTEM, /* dwFlagsAndAttributes */
NULL); /* hTemplateFile */
//std::cout << "COM: " << (int)nId << "\n";
if(hCOM == INVALID_HANDLE_VALUE)
{
//std::cout << "INVALID_HANDLE_VALUE \n" ;
DWORD err = GetLastError();
if (err == ERROR_FILE_NOT_FOUND)
{
std::cout << "Error: Failed to open COM[" << nId << "]\n";
}
else if(err == ERROR_INVALID_NAME)
{
std::cout << "\nError: \n%s 'filename, directory name, or volume label syntax is incorrect'\n"; //error code 0x7B
}
else
{
//cout << "\nHandle creation error code: %x\n" << err;
}
return 0;
}
else
{
std::cout << "COM[" << nId << "] OPEN. Baud: " << baud <<"\n";
}
// COM buffer size
SetupComm(hCOM, RX_SIZE, TX_SIZE);
// COM config
if(!SetCommTimeouts(hCOM, &g_cto) || !SetCommState(hCOM, &g_dcb))
{
CloseHandle(hCOM);
return 0;
}
// COM buffer purge
PurgeComm(hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
EscapeCommFunction(hCOM, SETDTR);
return hCOM;
#else
wxSerialPort *pwxSerialPort = new wxSerialPort();
char szPort[32];
sprintf(szPort,"com%d", nId);
if(pwxSerialPort->Open(szPort) < 0) {
return 0;
}
// set the baudrate
pwxSerialPort->SetBaudRate((wxBaud)baud);
return pwxSerialPort;
#endif
}
int CloseSerialPort(CommHandle hSerialPort)
{
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
CloseHandle(hSerialPort);
return 1;
#else
hSerialPort->Close();
delete hSerialPort;
return 1;
#endif
}
int WriteDataToSerialPort(CommHandle hSerialPort, void *pMsg, unsigned short messageLength, unsigned int *pBytesWritten)
{
*pBytesWritten = 0;
if(hSerialPort == 0)
{
//cout << "hSerialPort ====== 0";
return -1;
}
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
return WriteFile(hSerialPort, (char*)pMsg, messageLength, (DWORD*)pBytesWritten, NULL);
#else
*pBytesWritten = hSerialPort->Write((char*)pMsg, messageLength);
return 1;
#endif
}
int ReadDataFromSerialPort(CommHandle hSerialPort, void *pMsg, unsigned short messageLength, unsigned int *pBytesRead)
{
unsigned short i;
*pBytesRead = 0;
i = 0;
if(hSerialPort == 0)
{
return -1;
}
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
return ReadFile(hSerialPort, (char*)pMsg, messageLength, (DWORD*)pBytesRead, NULL);
#else
*pBytesRead = hSerialPort->Read((char*)pMsg, messageLength);
return 1;
#endif
}
Communication through serial port is slow.
You should use WriteFileEx instead of WriteFile.
You can specify a routine which may execute when the writting(transmitting) is completed or failed.
If you write next data after that routine has been executed, overflow of data may not be occured.

Resources