Converting an assembly jump command to its hex value in C - c

Im attempting to create an assembler in c which just reads the instructions from an input file and then translates them to their machine/hex code. So far so good until i hit the jump instruction, while i have it so that it translates the hex properly to in the case of jump 24 to c0 00 00 18 im unsure of how to check those 00's properly without hard coding it in. How can i do this? Should i be using shifts?
PR1.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *ltrim(char *s) {
while (*s == ' ' || *s == '\t') s++;
return s;
}
char getRegister(char *text) {
if (*text == 'r' || *text=='R') text++;
return atoi(text);
}
char getHex(char *text){
int number = (int)strtol(text, NULL, 16);
char reservednum[5];
if(number <= 0xFFFF){
sprintf(&reservednum[0], "%04x", number);
}
return atoi(reservednum);
}
int assembleLine(char *text, unsigned char* bytes) {
text = ltrim(text);
char *keyWord = strtok(text," ");
if (strcmp("add",keyWord) == 0) {
bytes[0] = 0x10;
bytes[0] |= getRegister(strtok(NULL," "));
bytes[1] = getRegister(strtok(NULL," ")) << 4 | getRegister(strtok(NULL," "));
return 2;
}
else if(strcmp("subtract", keyWord) == 0){
bytes[0] = 0x50;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
return 2;
}
else if(strcmp("and", keyWord) == 0){
bytes[0] = 0x20;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
return 2;
}
else if(strcmp("divide", keyWord) == 0){
bytes[0] = 0x30;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
return 2;
}
else if(strcmp("multiply", keyWord) == 0){
bytes[0] = 0x40;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
return 2;
}
else if(strcmp("or", keyWord) == 0){
bytes[0] = 0x60;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
return 2;
}
else if(strcmp("halt", keyWord) == 0){
bytes[0] = 0x00;
bytes[1] = 0x00;
return 2;
}
else if(strcmp("return", keyWord) == 0){
bytes[0] = 0x70;
bytes[1] = 0x00;
return 2;
}
else if(strcmp("addimmediate", keyWord) == 0){
bytes[0] = 0x90;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getHex(strtok(NULL, " "));
return 2;
}
else if(strcmp("interrupt", keyWord) == 0){
bytes[0] = 0x80;
bytes[0] |= getHex(strtok(NULL, " "));
bytes[1] = 0x00;
return 2;
}
else if(strcmp("push", keyWord) == 0){
bytes[0] = 0x70;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = 0x40;
return 2;
}
else if(strcmp("pop", keyWord) == 0){
bytes[0] = 0x70;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = 0x80;
return 2;
}
else if(strcmp("load", keyWord) == 0){
bytes[0] = 0xE0;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getHex(strtok(NULL, " "));
return 2;
}
else if(strcmp("store", keyWord) == 0){
bytes[0] = 0xF0;
bytes[0] |= getRegister(strtok(NULL, " "));
bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getHex(strtok(NULL, " "));
return 2;
}
else if(strcmp("jump", keyWord) == 0){
bytes[0] = 0xC0;
bytes[1] = 0x00;
bytes[2] = 0x00;
bytes[3] = getHex(strtok(NULL, " "));
return 4;
}
}
int main(int argc, char **argv) {
FILE *src = fopen(argv[1],"r");
FILE *dst = fopen(argv[2],"w");
while (!feof(src)) {
unsigned char bytes[4];
char line[1000];
if (NULL != fgets(line, 1000, src)) {
printf ("read: %s\n",line);
int byteCount = assembleLine(line,bytes);
fwrite(bytes,byteCount,1,dst);
}
}
fclose(src);
fclose(dst);
return 0;
}

Related

smBus communication testing for fan driver IC in STM32 with C

I developed a library for fan IC which use smbus protocol. However ı have some problems and questions.
1 -) what is diff between master and slave for smbus? whether the IC should be slave or master is not specified in the datasheet. Therefore, how can ı decide that stm32 developer board should be slave or master.
2-) unfortunately, ı cannot try my code because fan driver IC ı have not received yet sensor. Do u know any method to test my code. Maybe ardunio library.
3-) to receive data, ı firstly tranmit the register address of data ı want to read. is it correct.
You can find datasheet of IC and code ı wrote below
C file
#include "smbusDriver.h"
#include "stm32f0xx_hal_smbus.h"
#include "stm32f0xx_hal.h"
#include "smbusDriver.h"
resultConditions_t InitializeDriver(SMBUS_HandleTypeDef *hsmbus, uint8_t address, addressValues_t *Daddress){
Daddress->Fields.configurationRegisterAddress = 0x20;
Daddress->Fields.FanStatusRegisterAddress = 0x24;
Daddress->Fields.FanStallRegisterAddress = 0x25;
Daddress->Fields.FanSpinRegisterAddress = 0x26;
Daddress->Fields.DriveFailStatusAddress = 0x27;
Daddress->Fields.FanInterruptEnableRegisterAddress = 0x29;
Daddress->Fields.PwmPolarityRegisterAddress = 0x2A;
Daddress->Fields.PwmOutputTypeRegisterAddress = 0x2B;
Daddress->Fields.PwmFrequency45Address = 0x2C;
Daddress->Fields.PwmFrequency123Address = 0x2D;
Daddress->Fields.PwmDivider1Address = 0x31;
Daddress->Fields.PwmDivider2Address = 0x41;
Daddress->Fields.PwmDivider3Address = 0x51;
Daddress->Fields.PwmDivider4Address = 0x61;
Daddress->Fields.PwmSettingAddress1 = 0x30;
Daddress->Fields.PwmSettingAddress2 = 0x40;
Daddress->Fields.PwmSettingAddress3 = 0x50;
Daddress->Fields.PwmSettingAddress4 = 0x60;
resultConditions_t result = RESULT_OK;
uint8_t buf[2];
configuration_t confDriver;
confDriver.Fields.MASK = 0 ; // Alert pin activated.
confDriver.Fields.DIS_TO = 0; // smBUS enabled. If 1, I2C is compatible
confDriver.Fields.WD_EN = 0; // Watchdog is not enabled
confDriver.Fields.DRECK = 1; // Enabled internal clock
confDriver.Fields.USECK = 0; // Connecting internal oscillator
FanInterruptEnableRegister_t FanIntEn;
FanIntEn.Fields.F1ITEN = 1;
FanIntEn.Fields.F2ITEN = 1;
FanIntEn.Fields.F3ITEN = 1;
FanIntEn.Fields.F4ITEN = 1;
FanIntEn.Fields.F5ITEN = 0;
PwmPolarityRegister_t PwmPolarity;
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmOutputTypeRegister_t OutputType;
OutputType.Fields.PMOT1 = 0;
OutputType.Fields.PMOT2 = 0;
OutputType.Fields.PMOT3 = 0;
OutputType.Fields.PMOT4 = 0;
PwmFrequency45_t BaseFrequency_45;
PwmFrequency123_t BaseFrequency_123;
BaseFrequency_45.Fields.PwmFrequency4 = 0; // 26kHz
BaseFrequency_45.Fields.PwmFrequency5 = 0; // 26kHz
BaseFrequency_123.Fields.PwmFrequency1 = 0; // 26kHz
BaseFrequency_123.Fields.PwmFrequency2 = 0; // 26kHz
BaseFrequency_123.Fields.PwmFrequency3 = 0; // 26kHz
PwmDividerRegister_t Divider;
Divider.Fields.pwmDivider_1 = 0x01; // PWM Divider
Divider.Fields.pwmDivider_2 = 0x01; // PWM Divider
Divider.Fields.pwmDivider_3 = 0x01; // PWM Divider
Divider.Fields.pwmDivider_4 = 0x01; // PWM Divider
HAL_SMBUS_Init(hsmbus);
HAL_Delay(10);
uint16_t DeviceAddress = 0x0000;
DeviceAddress = DeviceAddress | address;
result = HAL_SMBUS_IsDeviceReady(hsmbus, DeviceAddress, 5 , 1000);
if (result != RESULT_OK) return result;
HAL_SMBUS_EnableAlert_IT(hsmbus);
if (result != RESULT_OK) return result;
HAL_SMBUS_EnableListen_IT(hsmbus);
if (result != RESULT_OK) return result;
HAL_Delay(20);
buf[0] = Daddress->Fields.configurationRegisterAddress; // The configuration of board is set
buf[1] = confDriver.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result != RESULT_OK) return result;
HAL_Delay(20);
buf[0] = Daddress->Fields.FanInterruptEnableRegisterAddress; // If any alert shows up, Fans can interrupt the operation
buf[1] = FanIntEn.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmPolarityRegisterAddress; // The high to high, low to low
buf[1] = PwmPolarity.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmOutputTypeRegisterAddress; // Pull-push and Open Drain choose
buf[1] = OutputType.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmFrequency45Address; // Base Frequency 4-5
buf[1] = BaseFrequency_45.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result; // Base Frequency 1-2-3
buf[0] = Daddress->Fields.PwmFrequency123Address;
buf[1] = BaseFrequency_123.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider1Address; // Divider of frequency => frequency / divide factor (Duty Cycle is not affected)
buf[1] = Divider.Fields.pwmDivider_1;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider2Address; // Divider of frequency
buf[1] = Divider.Fields.pwmDivider_2;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider3Address; // Divider of frequency
buf[1] = Divider.Fields.pwmDivider_3;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider4Address; // Divider of frequency
buf[1] = Divider.Fields.pwmDivider_4;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result != RESULT_OK) return result;
return result;
}
resultConditions_t setPwmConfig(uint8_t Pwm, addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
resultConditions_t result = HAL_OK;
PwmSettings_t pwmSet;
uint8_t buf[2];
pwmSet.Fields.pwmSettings1 = Pwm;
pwmSet.Fields.pwmSettings2 = Pwm;
pwmSet.Fields.pwmSettings3 = Pwm;
pwmSet.Fields.pwmSettings4 = Pwm;
uint16_t DeviceAddress = 0x0000;
DeviceAddress = DeviceAddress | address;
buf[0] = Daddress->Fields.PwmSettingAddress1; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings1;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmSettingAddress2; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings2;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmSettingAddress3; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings3;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmSettingAddress4; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings4;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
return result;
}
generalStatus_t getGeneralStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.FanStatusRegisterAddress;
generalStatus_t returnValue = NO_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf+1,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000){
returnValue = DRIVE_FAIL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b01000000) == (uint8_t)0b01000000){
returnValue = FAN_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000)
{
returnValue = FAN_STALL_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
specialFanStallStatus_t getStallStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.FanStallRegisterAddress;
specialFanStallStatus_t returnValue = NO_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_1_STALL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_2_STALL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
{
returnValue = FAN_3_STALL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
{
returnValue = FAN_4_STALL_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
specialFanSpinStatus_t getSpinStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.FanSpinRegisterAddress;
specialFanSpinStatus_t returnValue = NO_SPIN_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_1_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_2_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
{
returnValue = FAN_3_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
{
returnValue = FAN_4_SPIN_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
specialFanDriveStatus_t getDriveStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.DriveFailStatusAddress;
specialFanDriveStatus_t returnValue = NO_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_1_DRIVE_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_2_DRIVE_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
{
returnValue = FAN_3_DRIVE_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
{
returnValue = FAN_4_DRIVE_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
H file
#ifndef smbusDriver
#define smbusDriver
#ifdef __cplusplus
extern "C" {
#endif
#include "smbusDriver.h"
#include "stm32f0xx_hal_smbus.h"
#include "stm32f0xx_hal.h"
typedef union {
struct{
uint8_t configurationRegisterAddress;
uint8_t FanStatusRegisterAddress;
uint8_t FanStallRegisterAddress;
uint8_t FanSpinRegisterAddress;
uint8_t DriveFailStatusAddress;
uint8_t FanInterruptEnableRegisterAddress;
uint8_t PwmPolarityRegisterAddress;
uint8_t PwmOutputTypeRegisterAddress;
uint8_t PwmFrequency45Address;
uint8_t PwmFrequency123Address;
uint8_t PwmDivider1Address;
uint8_t PwmDivider2Address;
uint8_t PwmDivider3Address;
uint8_t PwmDivider4Address;
uint8_t PwmSettingAddress1;
uint8_t PwmSettingAddress2;
uint8_t PwmSettingAddress3;
uint8_t PwmSettingAddress4;
}Fields;
}addressValues_t;
typedef enum{
NO_ERROR,
DRIVE_FAIL_ERROR, // indicate that one or more fan could not be driven (ProgrammingError)
FAN_SPIN_ERROR, // indicate that one or more fan spin
FAN_STALL_ERROR, // indicate that one or more fan is stuck
UNEXPECTED_ERROR
} generalStatus_t;
typedef enum {
NO_STALL_ERROR,
FAN_5_STALL_ERROR,
FAN_4_STALL_ERROR,
FAN_3_STALL_ERROR,
FAN_2_STALL_ERROR,
FAN_1_STALL_ERROR,
UNEXPECTED_STALL_ERROR
} specialFanStallStatus_t;
typedef enum {
NO_SPIN_ERROR,
FAN_5_SPIN_ERROR,
FAN_4_SPIN_ERROR,
FAN_3_SPIN_ERROR,
FAN_2_SPIN_ERROR,
FAN_1_SPIN_ERROR,
UNEXPECTED_SPIN_ERROR
} specialFanSpinStatus_t;
typedef enum {
NO_DRIVE_ERROR,
FAN_5_DRIVE_ERROR,
FAN_4_DRIVE_ERROR,
FAN_3_DRIVE_ERROR,
FAN_2_DRIVE_ERROR,
FAN_1_DRIVE_ERROR,
UNEXPECTED_DRIVE_ERROR
} specialFanDriveStatus_t;
typedef enum{
RESULT_OK,
RESULT_ERROR,
RESULT_TIMEOUT,
RESULT_BUSY,
RESULT_INVALID,
} resultConditions_t;
typedef union {
struct {
uint8_t USECK : 1; // 1 => External Clock & 0 => Internal Clock
uint8_t DRECK : 1; // 1 => Clock pin output and push-pull driver 0 => Clock pin input
uint8_t reserved : 3;
uint8_t WD_EN : 1; // 1 => Watch clock is activated 0 => 0 watch clock is deactivated.
uint8_t DIS_TO : 1; // 1 => I2C is compatible 0 => SMBus time-out is enabled
uint8_t MASK : 1; // 1 => Alert is deactivated 0 => Alert is activated
} Fields;
uint8_t value;
} configuration_t;
typedef union {
struct
{
uint8_t FNSTL : 1; // stall error <=> 1
uint8_t FNSPIN : 1; // Spin up error <=> 1
uint8_t DVFAIL : 1; // Maximum speed PWM error <=> 1
uint8_t reserved : 5;
}Fields;
uint8_t value;
}FanStatusRegister_t;
typedef union {
struct {
uint8_t F1STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F2STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F3STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F4STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F5STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t reserved : 3; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
} Fields;
uint8_t value;
} FanStallStatusRegister_t;
typedef union {
struct {
uint8_t F1SPIN : 1; // spin start error <=> 1
uint8_t F2SPIN : 1; // spin start error <=> 1
uint8_t F3SPIN : 1; // spin start error <=> 1
uint8_t F4SPIN : 1; // spin start error <=> 1
uint8_t F5SPIN : 1; // spin start error <=> 1
uint8_t reserved : 3; // spin start error <=> 1
} Fields;
uint8_t value;
}FanSpinStatusRegister_t;
typedef union {
struct{
uint8_t DRVF1 : 1; // rpm error <=> 1
uint8_t DRVF2 : 1; // rpm error <=> 1
uint8_t DRVF3 : 1; // rpm error <=> 1
uint8_t DRVF4 : 1; // rpm error <=> 1
uint8_t DRVF5 : 1; // rpm error <=> 1
uint8_t reserved : 3; // rpm error <=> 1
}Fields;
uint8_t value;
} DriveFailStatus_t;
typedef union {
struct {
uint8_t F1ITEN : 1; // Alert Fan 1 enable <=> 1
uint8_t F2ITEN : 1; // Alert Fan 2 enable <=> 1
uint8_t F3ITEN : 1; // Alert Fan 3 enable <=> 1
uint8_t F4ITEN : 1; // Alert Fan 4 enable <=> 1
uint8_t F5ITEN : 1; // Alert Fan 5 enable <=> 1
uint8_t reserved : 3;
}Fields;
uint8_t value;
}FanInterruptEnableRegister_t;
typedef union {
struct {
uint8_t PLRITY1 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY2 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY3 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY4 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY5 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t reserved : 3;
}Fields;
uint8_t value;
}PwmPolarityRegister_t;
typedef union {
struct {
uint8_t PMOT1 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT2 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT3 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT4 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT5 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t reserved : 3;
} Fields;
uint8_t value;
} PwmOutputTypeRegister_t;
typedef union {
struct {
uint8_t PwmFrequency4 : 2;
uint8_t PwmFrequency5 : 2;
uint8_t reserved : 4;
}Fields;
uint8_t value;
}PwmFrequency45_t;
typedef union {
struct {
uint8_t PwmFrequency1 : 2;
uint8_t PwmFrequency2 : 2;
uint8_t PwmFrequency3 : 2;
uint8_t reserved : 2;
}Fields;
uint8_t value;
}PwmFrequency123_t;
typedef union {
struct {
uint8_t DriveSetting_1: 8;
uint8_t DriveSetting_2: 8;
uint8_t DriveSetting_3: 8;
uint8_t DriveSetting_4: 8;
}Fields;
uint32_t value;
}CurrentDriveSettings_t;
typedef union {
struct{
uint8_t pwmDivider_1 :8;
uint8_t pwmDivider_2 :8;
uint8_t pwmDivider_3 :8;
uint8_t pwmDivider_4 :8;
}Fields;
uint32_t value;
}PwmDividerRegister_t;
typedef union{
struct {
uint8_t pwmSettings1 :8;
uint8_t pwmSettings2 :8;
uint8_t pwmSettings3 :8;
uint8_t pwmSettings4 :8;
}Fields;
}PwmSettings_t;
resultConditions_t InitializeDriver(SMBUS_HandleTypeDef *hsmbus, uint8_t address, addressValues_t *Daddress);
resultConditions_t setPwmConfig(uint8_t Pwm, addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address);
generalStatus_t getGeneralStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address);
#endif
Datasheet: https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/EMC2301-2-3-5-Data-Sheet-DS20006532A.pdf
Estimation whether code is working or not
Firstly, I would recommend that you use STM's library AN4502.
The difference between the master and the slave is the same as for the i2c bus. All bus transfers are initialized by the master.
I think there is not emulator of EMC2301. But to test the bus you can use examples from the STM AN4502.
Your code won't work because the HAL_SMBUS_Master_Transmit_IT and HAL_SMBUS_Master_Receive_IT functions are called asynchronously and require you to wait for the execution to finish when you call two functions in a row, you will get the result HAL_BUSY. Use the library AN4502, it will make it easier to interact with the peripheral.

How can I reduce the size of my code and get the same result

Is there a way to get the same result with a smaller size of code in c?
My Function:
void PCA9575_set_gpio_level(uint8_t gpio_num, uint8_t level) {
uint8_t reg, data, pin;
uint8_t buf[1] = {0};
buf[1] = PCA9575_read_register(OUT0);
if (gpio_num >= 28 && gpio_num <= 35) {
reg = OUT0;
pin = gpio_num - 27;
if (pin == 3) {
pin = 4;
} else if (pin == 4) {
pin = 8;
} else if (pin == 5) {
pin = 16;
} else if (pin == 6) {
pin = 32;
} else if (pin == 7) {
pin = 64;
} else if (pin == 8) {
pin = 128;
} else {
return;
}
if (level == 1) {
if (buf[1] == 0) {
data = pin;
} else if (buf[1] == 0xFF) {
data = 0xFF;
} else {
data = buf[1] ^ pin;
}
} else if (level == 0) {
if (buf[1] == 0) {
data = 0;
} else {
data = buf[1] ^ pin;
}
} else {
return;
}
}
else if (gpio_num >= 36 && gpio_num <= 43) {
reg = OUT1;
pin = gpio_num - 35;
if (pin == 3) {
pin = 4;
} else if (pin == 4) {
pin = 8;
} else if (pin == 5) {
pin = 16;
} else if (pin == 6) {
pin = 32;
} else if (pin == 7) {
pin = 64;
} else if (pin == 8) {
pin = 128;
} else {
return;
}
if (level == 1) {
if (buf[1] == 0) {
data = pin;
} else {
data = buf[1] ^ pin;
}
} else if (level == 0) {
if (buf[1] == 0) {
data = 0;
} else {
data = buf[1] ^ pin;
}
} else {
return;
}
}
else {
return;
}
PCA9575_write_to_register(reg, data);
}
The buf[1] variable is a value from 00000000 - 11111111 which is based on what has already been set.
The data variable is a value from 00000000 - 11111111 which will set the gpio pins.
The code should read what gpio pins are set and keep them set. Also at the same time set the new desired gpio pin.
GPIO pins are values from 28 - 43.
maybe:
void PCA9575_set_gpio_level(uint8_t gpio_num, uint8_t level)
{
uint8_t reg, pin;
uint8_t buf = PCA9575_read_register(OUT0);
if (gpio_num > 27 && gpio_num < 36)
{
reg = OUT0;
pin = gpio_num - 27;
}
else
{
if (gpio_num > 35 && gpio_num < 44)
{
reg = OUT1;
pin = gpio_num - 35;
}
}
else return;
pin = 1 << (pin - 1);
if(level < 2)
{
if(!buf) data = level * pin;
else if(buf == 0xff && gpio_num < 36) data = 0xff;
else data = buf ^pin;
}
PCA9575_write_to_register(reg, data);
}

I'm trying to make a morse code transmitter with the AtMega 32u4, but the microprocessor dosen't sees my input buttons and i don't know why?

I have an Adafruit feather 32u4 LoRa transmitter, I want to make a digital Morse transmitter, I took the transmission code from the internet and decided to write my own code for the rest. The two transistors transmit to each other but the micro don sees my input buttons.
int StatoPrecP2 = 0;
int i;
char SendData;
void loop()
{
switch (Stato) {
StatoAttP1 = digitalRead(P_Riga);
StatoAttP2 = digitalRead (P_Punto);
case 0:
if (StatoAttP1 == 1) /*&& (StatoPrecP1 != StatoAttP1 )) */{
digitalWrite(ButtonRecived, HIGH);
delay (250);
digitalWrite(ButtonRecived, LOW);
Stato = 1;
SendData = ".";
}
if ((StatoAttP2 == 1) && (StatoPrecP2 != StatoAttP1)) {
digitalWrite(ButtonRecived, 1);
delay (250);
digitalWrite(ButtonRecived, 0);
Stato = 1;
SendData = "-";
}
if (rf95.available())
{
// Should be a message for us now
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.recv(buf, &len))
{
digitalWrite(LED, HIGH);
RH_RF95::printBuffer("Received: ", buf, len);
Serial.print("Got: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
if (*buf = ".") {
PORTF = PORTF | 0x20;
delay(1000);
PORTF = PORTF & ~0x20;
}
else if (*buf = "-") {
PORTF = PORTF | 0x20;
delay(2500);
PORTF = PORTF & ~0x20;
}
}
else
{
Serial.println("Receive failed");
}
case 1:
// Send a reply
for (i = 0; i < 5000; i++) {
uint8_t data = SendData;
rf95.send(data, sizeof(data));
rf95.waitPacketSent();
Serial.println("Sent a reply");
digitalWrite(LED, LOW);
if ((StatoAttP1 = 1) & (StatoAttP1 != StatoPrecP1)) {
PORTF = PORTF | 0x10;
delay (250);
PORTF = PORTF & ~0x10;
Stato = 1;
uint8_t data[] = ".";
i = 0;
}
else if ((StatoAttP2 = 1) & (StatoAttP2 != StatoPrecP2)) {
PORTF = PORTF | 0x10;
delay (250);
PORTF = PORTF & ~0x10;
Stato = 1;
uint8_t data[] = "-";
i = 0;
}
delay (1);
}
Stato = 0;
}
}
StatoPrecP1 = StatoAttP1;
StatoPrecP2 = StatoAttP2;
}
While it's allowed to put statements inside a switch that still are outside any case, those will simply not be executed.
You have:
switch (Stato) {
StatoAttP1 = digitalRead(P_Riga);
StatoAttP2 = digitalRead (P_Punto);
case 0:
But the two digitalRead calls will never happen, which is the source of your problem.
You need to place those statements outside the switch:
StatoAttP1 = digitalRead(P_Riga);
StatoAttP2 = digitalRead (P_Punto);
switch (Stato) {
case 0:
A decent compiler should be able to warn about this problem, and if not you need to enable more warnings. And you should treat those warnings as errors the must be fixed.

glibc detected realloc(): invalid pointer

Im constantly getting this when I build on Qtcreator.
*** glibc detected *** /home/Exxamples/EffectivCons: realloc(): invalid pointer: 0xb6fb5414 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb6603ee2]
/lib/i386-linux-gnu/libc.so.6(realloc+0x25d)[0xb660856d]
/lib/i386-linux-gnu/libc.so.6(realloc+0x273)[0xb6608583]
/opt/Qt5.1.1/5.1.1/gcc/lib/libQt5Core.so.5(_ZN9QListData7reallocEi+0x37)[0xb6906e67]
/opt/Qt5.1.1/5.1.1/gcc/lib/libQt5Core.so.5(_ZN9QListData6appendEi+0x7c)[0xb6906f4c]
/opt/Qt5.1.1/5.1.1/gcc/lib/libQt5Core.so.5(_ZN9QListData6appendEv+0x23)[0xb6906fd3]
/opt/Qt5.1.1/5.1.1/gcc/lib/libQt5Core.so.5(+0x1afa3e)[0xb6a05a3e]
/opt/Qt5.1.1/5.1.1/gcc/lib/libQt5Core.so.5(_Z21qRegisterResourceDataiPKhS0_S0_+0x216)[
This is my code, through the other questions on the website, I saw some users using malloc or realloc, but Im not using it, why am i getting an error?
#include <termios.h>
#include <string.h>
#include <stdlib.h>
#define BUFLEN 512
std::string numberToString(const int n);
void sendExpressivAnimation(int,EmoStateHandle eState);
void handleExpressivEvent(std::ostream& os, EmoEngineEventHandle expressivEvent);
bool handleUserInput();
void promptUser();
void nonblocking();
int getch();
int kbhit();
int createSocket();
int startSendPort = 30000;
struct termios initial_settings, new_settings;
int kbhit (void)
{
struct timeval tv;
fd_set rdfs;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rdfs);
FD_SET (STDIN_FILENO, &rdfs);
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &rdfs);
}
int main(int argc, char **argv)
{
EmoEngineEventHandle eEvent = EE_EmoEngineEventCreate();
EmoStateHandle eState = EE_EmoStateCreate();
unsigned int userID = 0;
const int CONTROL_PANEL_PORT = 3008;
bool connected = false;
if(EE_EngineRemoteConnect("127.0.0.1", CONTROL_PANEL_PORT)== EDK_OK)
{
std::cout <<"Emotiv Engine started" << std::endl;
connected = true;
}
else
{
std::cout <<"Emotiv Engine failed !"<< std::endl;
connected = false;
}
std::cout << "Type \"exit\" to quit, \"help\" to list available commands..." << std::endl;
promptUser();
int _socket;
_socket = createSocket();
if(connected)
{
nonblocking();
fflush(stdin);
while (true) {
// Handle the user input
//if (_kbhit()) {
if (!handleUserInput()) {
break;
}
//}
int state = EE_EngineGetNextEvent(eEvent);
// New event needs to be handled
if (state == EDK_OK) {
EE_Event_t eventType = EE_EmoEngineEventGetType(eEvent);
EE_EmoEngineEventGetUserId(eEvent, &userID);
switch (eventType) {
// New headset connected, create a new socket to send the animation
case EE_UserAdded:
{
std::cout << std::endl << "New user " << userID << " added, sending Expressiv animation to ";
std::cout << "127.0.0.1" << ":" << startSendPort << "..." << std::endl;
promptUser();
break;
}
// Headset disconnected, remove the existing socket
case EE_UserRemoved:
{
std::cout << std::endl << "User " << userID << " has been removed." << std::endl;
promptUser();
break;
}
// Send the Expressiv animation if EmoState has been updated
case EE_EmoStateUpdated:
{
//std::cout << "New EmoState from user " << userID << "..." << std::endl;
EE_EmoEngineEventGetEmoState(eEvent, eState);
sendExpressivAnimation(_socket,eState);
break;
}
// Handle Expressiv training event
case EE_ExpressivEvent:
{
handleExpressivEvent(std::cout, eEvent);
break;
}
default:
break;
}
}
else if (state != EDK_NO_EVENT) {
std::cout << std::endl << "Internal error in Emotiv Engine!" << std::endl;
break;
}
}
}
EE_EngineDisconnect();
EE_EmoStateFree(eState);
EE_EmoEngineEventFree(eEvent);
return 0;
}
std::string numberToString(const int n) {
char* buf;
//_itoa(n, buf, 10);
QString nStr = QString::number(n);
buf = nStr.toLocal8Bit().data();
return std::string(buf);
}
void sendExpressivAnimation(int _socket,EmoStateHandle eState) {
std::ostringstream output;
EE_ExpressivAlgo_t upperFaceType = ES_ExpressivGetUpperFaceAction(eState);
EE_ExpressivAlgo_t lowerFaceType = ES_ExpressivGetLowerFaceAction(eState);
float upperFaceAmp = ES_ExpressivGetUpperFaceActionPower(eState);
float lowerFaceAmp = ES_ExpressivGetLowerFaceActionPower(eState);
if (ES_ExpressivIsBlink(eState)) {
output << "B,";
}
if (ES_ExpressivIsLeftWink(eState)) {
output << "l,";
}
if (ES_ExpressivIsRightWink(eState)) {
output << "r,";
}
if (ES_ExpressivIsLookingRight(eState)) {
output << "R,";
}
if (ES_ExpressivIsLookingLeft(eState)) {
output << "L,";
}
if (upperFaceAmp > 0.0) {
switch (upperFaceType) {
case EXP_EYEBROW: output << "b"; break;
case EXP_FURROW: output << "f"; break;
default: break;
}
output << numberToString(static_cast<int>(upperFaceAmp*100.0f)) << ",";
}
if (lowerFaceAmp > 0.0) {
switch (lowerFaceType) {
case EXP_CLENCH: output << "G"; break;
case EXP_SMILE: output << "S"; break;
case EXP_LAUGH: output << "H"; break;
case EXP_SMIRK_LEFT: output << "sl"; break;
case EXP_SMIRK_RIGHT: output << "sr"; break;
default: break;
}
output << numberToString(static_cast<int>(lowerFaceAmp*100.0f)) << ",";
}
std::string outString = output.str();
// Remove the last comma
if (outString.length()) {
outString.resize(outString.length()-1);
}
if (!outString.length()) {
outString = std::string("neutral");
}
if(send(_socket, outString.c_str(), BUFLEN, 0)==-1)
{
std::cout<<"sending error"<<std::endl;
//exit(1);
}
}
void handleExpressivEvent(std::ostream& os, EmoEngineEventHandle expressivEvent) {
unsigned int userID = 0;
EE_EmoEngineEventGetUserId(expressivEvent, &userID);
EE_ExpressivEvent_t eventType = EE_ExpressivEventGetType(expressivEvent);
switch (eventType) {
case EE_ExpressivTrainingStarted:
{
os << std::endl << "Expressiv training for user " << userID << " STARTED!" << std::endl;
break;
}
case EE_ExpressivTrainingSucceeded:
{
os << std::endl << "Expressiv training for user " << userID << " SUCCEEDED!" << std::endl;
break;
}
case EE_ExpressivTrainingFailed:
{
os << std::endl << "Expressiv training for user " << userID << " FAILED!" << std::endl;
break;
}
case EE_ExpressivTrainingCompleted:
{
os << std::endl << "Expressiv training for user " << userID << " COMPLETED!" << std::endl;
break;
}
case EE_ExpressivTrainingDataErased:
{
os << std::endl << "Expressiv training data for user " << userID << " ERASED!" << std::endl;
break;
}
case EE_ExpressivTrainingRejected:
{
os << std::endl << "Expressiv training for user " << userID << " REJECTED!" << std::endl;
break;
}
case EE_ExpressivTrainingReset:
{
os << std::endl << "Expressiv training for user " << userID << " RESET!" << std::endl;
break;
}
case EE_ExpressivNoEvent:
default:
//## unhandled case
assert(0);
return;
}
promptUser();
}
bool handleUserInput() {
static std::string inputBuffer;
char c = getch();
if ((int)c == 10) {
std::cout << std::endl;
std::string command;
const size_t len = inputBuffer.length();
command.reserve(len);
// Convert the input to lower case first
for (size_t i=0; i < len; i++) {
command.append(1, tolower(inputBuffer.at(i)));
}
inputBuffer.clear();
bool success = parseCommand(command, std::cout);
promptUser();
return success;
}
else {
if ((int)c == 127) { // Backspace key
if (inputBuffer.length()) {
putchar('\b');
putchar(' ');
putchar('\b');
inputBuffer.erase(inputBuffer.end()-1);
}
}
else {
std::cout << c;
if(((int) c == 32) || ((int)c == 95) || (((int)c >= 97 && (int)c <=122)) || (((int)c >=48 && (int)c <= 57)))
inputBuffer.append(1,c);
}
}
return true;
}
void promptUser()
{
std::cout << "ExpressivDemo> "<<std::endl;
}
void nonblocking()
{
tcgetattr(0, &initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
//new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 0;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
int getch()
{
int r;
unsigned char c=0;
if((r = read(0, &c, sizeof(c))) < 0 )
{
return r;
}
else
{
return c;
}
}
int createSocket()
{
struct sockaddr_in si_other;
int s, slen = sizeof(si_other);
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
std::cout<<"socket"<<std::endl;
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(startSendPort);
if (inet_aton("127.0.0.1", &si_other.sin_addr)==0)
{
std::cout<<"intet_aton failed !"<<std::endl;
//exit(1);
}
if(connect(s,(sockaddr*)&si_other,slen)==-1)
{
std::cout<<"connect failed !"<<std::endl;
// exit(1);
}
return s;
}
Your code is too big to be checked wholly. If you can reduce it to a SSCCE it will be easier for everybody.
Anyway, skimming over your code, only one thing catched my eye:
char *buf;
QString nStr = QString::number(n);
buf = nStr.toLocal8Bit().data();
return std::string(buf);
The call to toLocal8Bit() returns a temporary QByteArray and then you call its data() member function. The returned pointer is only valid during the lifetime of that temporary, that is, until the ending ;. After that the buf pointer is invalid and the next line renders undefined behavior.
You should do something like:
QString nStr = QString::number(n);
QByteArray a(nStr.toLocal8Bit());
char *buf = a.data();
return std::string(buf);
Or even better:
QString nStr = QString::number(n);
return std::string(nStr.toLocal8Bit().data());
Or just for show:
return std::string(QString::number(n).toLocal8Bit().data());

Uiimage to Base64 and back

I tri to convert NSData to Base64 to save an UIImage in the database, in a blob, that is located at a remote server.
To parse:
NSData *imagenData = UIImagePNGRepresentation(self.imagen.image);
MetodosComunes *metodos = [[MetodosComunes alloc] init];
NSString *imagenStr = [metodos base64forData:imagenData];
The method base64forData:
-(NSString*)base64forData:(NSData*)theData {
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
}
Then, i need to show this saved image at the application, and i convert base64 to NSData:
- (NSData *)base64DataFromString: (NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[3];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil)
{
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true)
{
if (ixtext >= lentext)
{
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z'))
{
ch = ch - 'A';
}
else if ((ch >= 'a') && (ch <= 'z'))
{
ch = ch - 'a' + 26;
}
else if ((ch >= '0') && (ch <= '9'))
{
ch = ch - '0' + 52;
}
else if (ch == '+')
{
ch = 62;
}
else if (ch == '=')
{
flendtext = true;
}
else if (ch == '/')
{
ch = 63;
}
else
{
flignore = true;
}
if (!flignore)
{
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext)
{
if (ixinbuf == 0)
{
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2))
{
ctcharsinbuf = 1;
}
else
{
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4)
{
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++)
{
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak)
{
break;
}
}
}
return theData;
}
When i show the image, the image is black. At the console appear this error:
May 16 17:04:13 MacBook-Pro-de-Alejandro.local pantallas[1608] : ImageIO: PNG invalid PNG file: iDOT doesn't point to valid IDAT chunk May 16 17:04:13 MacBook-Pro-de-Alejandro.local pantallas[1608] : ImageIO: PNG Extra compressed data

Resources